采用字典树解题。
struct TrieNode {int frequency = 0;TrieNode* child[26];TrieNode() {for (int i = 0; i < 26; ++i) {child[i] = nullptr;}}
};class Solution {
private:TrieNode* root;public:vector findNumOfValidWords(vector& words, vector& puzzles) {root = new TrieNode();auto add = [&](const string& word) {TrieNode* cur = root;for (char ch: word) {if (!cur->child[ch - 'a']) {cur->child[ch - 'a'] = new TrieNode();}cur = cur->child[ch - 'a'];}++cur->frequency;};// 在回溯的过程中枚举 puzzle 的所有子集并统计答案// find(puzzle, required, cur, pos) 表示 puzzle 的首字母为 required, 当前搜索到字典树上的 cur 节点,并且准备枚举 puzzle 的第 pos 个字母是否选择(放入子集中)// find 函数的返回值即为谜底的数量function find = [&](const string& puzzle, char required, TrieNode* cur, int pos) {// 搜索到空节点,不合法,返回 0if (!cur) {return 0;}// 整个 puzzle 搜索完毕,返回谜底的数量if (pos == 7) {return cur->frequency;}// 选择第 pos 个字母int ret = find(puzzle, required, cur->child[puzzle[pos] - 'a'], pos + 1);// 当 puzzle[pos] 不为首字母时,可以不选择第 pos 个字母if (puzzle[pos] != required) {ret += find(puzzle, required, cur, pos + 1);}return ret;};for (string word: words) {// 将 word 中的字母按照字典序排序并去重sort(word.begin(), word.end());word.erase(unique(word.begin(), word.end()), word.end());// 加入字典树中add(word);}vector ans;for (string puzzle: puzzles) {char required = puzzle[0];sort(puzzle.begin(), puzzle.end());ans.push_back(find(puzzle, required, root, 0));}return ans;}
};
聚合函数就用来输入多个数据,输出一个数据的。如SUM()或MAX(),而每个聚合函数的输入就是每一个多数据的单元格。
# Write your MySQL query statement below
select id,sum(case month when 'Jan' then revenue end) as Jan_Revenue,sum(case month when 'Feb' then revenue end) as Feb_Revenue,sum(case month when 'Mar' then revenue end) as Mar_Revenue,sum(case month when 'Apr' then revenue end) as Apr_Revenue,sum(case month when 'May' then revenue end) as May_Revenue,sum(case month when 'Jun' then revenue end) as Jun_Revenue,sum(case month when 'Jul' then revenue end) as Jul_Revenue,sum(case month when 'Aug' then revenue end) as Aug_Revenue,sum(case month when 'Sep' then revenue end) as Sep_Revenue,sum(case month when 'Oct' then revenue end) as Oct_Revenue,sum(case month when 'Nov' then revenue end) as Nov_Revenue,sum(case month when 'Dec' then revenue end) as Dec_Revenue
from Department
group by id
过于简单以至于不知道该说什么
class Solution {
public:int distanceBetweenBusStops(vector& distance, int start, int destination) {if (start > destination) {swap(start, destination);}return min(accumulate(distance.begin() + start, distance.begin() + destination, 0),accumulate(distance.begin(), distance.begin() + start, 0) +accumulate(distance.begin() + destination, distance.end(), 0));}
};
只要知道一个最早的日期和星期几,然后减法求一下即可1
class Solution {
public:string dayOfTheWeek(int day, int month, int year) {vector week = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};vector monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30};/* 输入年份之前的年份的天数贡献 */int days = 365 * (year - 1971) + (year - 1969) / 4;/* 输入年份中,输入月份之前的月份的天数贡献 */for (int i = 0; i < month - 1; ++i) {days += monthDays[i];}if ((year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) && month >= 3) {days += 1;}/* 输入月份中的天数贡献 */days += day;return week[(days + 3) % 7];}
};
这道题由求子数组的最大和演变而来,唯一的不同的是子数组中,有可能被删除一项,为了分析问题方便,我们这边用一个标志位来表示子数组中是否已经删除了一项,因此这里状态表示可以用f[i][2]来表示。
其中f[i][0]表示以arr[i]结尾的且未删除元素的子数组的最大和
f[i][1]表示以arr[i]结尾的且删除了一个元素的子数组的最大和
f[i][0] = max(f[i - 1][0] + a[i],a[i]);
f[i][1] = max(f[i - 1][0],f[i - 1][1] + a[i]);
class Solution {
public:int maximumSum(vector& arr) {int dp0 = arr[0];// First deletion will leads to empty string as a potential answer,// which should be avoided. So we set a out of range valueint dp1 = -100000;int maximum = dp0;for (int i = 1; i < arr.size(); ++i) {int ndp0 = max(dp0 + arr[i], arr[i]);int ndp1 = max(dp0, dp1 + arr[i]);maximum = max(maximum, max(ndp0, ndp1));dp0 = ndp0;dp1 = ndp1;}return maximum;}
};
本题首先对arr2除重和排序,这个毫无疑问。然后就是关键点了:从后往前操作,每次尽可能取大的值替换。下一个就是dp的核心:每次可以选择,改变当前的值或者改变前一个值,因此可以完成min(dp[i - 2], dp[i - 1])
class Solution {
public:int maxv = 1e9;int makeArrayIncreasing(vector& arr1, vector& arr2) {// 预处理:排序,去重,加哨兵sort(arr2.begin(), arr2.end());arr2.erase(unique(arr2.begin(), arr2.end()), arr2.end());arr1.push_back(maxv + 5); // 右侧哨兵 infarr1.insert(arr1.begin(), -1); // 左侧哨兵 -1vector dp(arr1.size(), maxv);dp[0] = 0;for(int i = 1; i < arr1.size(); ++i) {int j = lower_bound(arr2.begin(),arr2.end(), arr1[i]) - arr2.begin();for(int k = 1; k <= min(i-1,j); ++k){ // 1. 枚举替换的个数 k = 1 to min(i-1,j)if(arr1[i-k-1] < arr2[j-k]) {dp[i] = min(dp[i], dp[i-k-1] + k);}}if(arr1[i-1] < arr1[i]) { // 2. 不替换 arr1[i-1]dp[i] = min(dp[i], dp[i-1]);}}int res = dp[arr1.size()-1];return (res >= maxv)? -1 : res;}
};
用数组分别存储各不同字母的数量,对l和o除2,然后取最小数即为可以拼凑多少个单词。
class Solution {
public:int maxNumberOfBalloons(string text) {vector cnt(5);for (auto & ch : text) {if (ch == 'b') {cnt[0]++;} else if (ch == 'a') {cnt[1]++;} else if (ch == 'l') {cnt[2]++;} else if (ch == 'o') {cnt[3]++;} else if (ch == 'n') {cnt[4]++;}}cnt[2] /= 2;cnt[3] /= 2;return *min_element(cnt.begin(), cnt.end());}
};
上一篇:MySQL基础-多表查询
下一篇:Java开启异步线程的几种方法