- 306 Addtive Number
题意:判断一个字符串能不能构成连加字符串
def isAdditiveNumber(self, num):
n = len(num)
for i, j in itertools.combinations(range(1, n), 2):
a, b = num[:i], num[i:j]
if b != str(int(b)):
continue
while j < n:
c = str(int(a) + int(b))
if not num.startswith(c, j):
break
j += len(c)
a, b = b, c
if j == n:
return True
return False
class Solution {
public:
bool isAdditiveNumber(string num) {
int size = num.size();
if(size < 3) return false;
for(int i = 1;i < size;++ i){
// while(num[i] == '0' && i < size && i > 1) ++ i;
for(int j = i + 1;j < size;++ j){
// while(num[j] == '0' && j < size && i + 1 < j) ++ j;
string add1 = num.substr(0,i);
string add2 = num.substr(i,j - i);
// cout< size) return false;
if(result == num.substr(index,result.size())){
return help_judge(num,index + result.size(),add2,result);
}
return false;
}
string help_add(string add1,string add2){
int size1 = add1.size();
int size2 = add2.size();
if(size1 < size2) return help_add(add2,add1);
int index = size1 - 1;
int index2 = size2 - 1;
int tmp = 0;
while(index >= 0){
int a1 = add1[index] - '0';
int a2 = index2 >= 0 ? add2[index2] - '0' : 0;
int result = a1 + a2 + tmp;
add1[index] = to_string(result % 10)[0];
tmp = result / 10;
index --;
index2 --;
}
if(tmp > 0) add1.insert(0,to_string(tmp));
return add1;
}
};
- 307 Range Sum Query - Mutable
题意:线段树的经典题目
思路:可以当做hard来做,因为涉及到了比较经典的数据结构,而且使用范围非常小,其实没必要做。要是想要知道线段树的构造和应用的话,可以看一下下面这篇文章:https://blog.csdn.net/Yaokai_AssultMaster/article/details/79599809。
- 309 Best Time to Buy and Sell Stock with Cooldown
题意:股票交易,买卖之间需要有缓冲时间
思路:构造sell,buy,rest三种情况的dp数组
class Solution {
public:
int maxProfit(vector& prices) {
int size = prices.size();
if(size == 0) return 0;
vector buy(size,0);
vector sell(size,0);
vector rest(size,0);
buy[0] = prices[0] * (-1);
sell[0] = 0;
rest[0] = 0;
for(int i = 1;i < size; ++ i){
buy[i] = max(buy[i - 1],rest[i - 1] - prices[i]);
sell[i] = max(sell[i - 1],buy[i - 1] + prices[i]);
rest[i] = max(buy[i - 1],max(sell[i - 1],rest[i - 1]));
}
return max(buy[size - 1],max(sell[size - 1],rest[size - 1]));
}
};
- 310 Minimum Height Trees
题意:深度最小树的根节点集合
思路:剥洋葱
class Solution {
public:
vector findMinHeightTrees(int n, vector>& edges) {
if(edges.size() == 0){
if(n == 1) return{0};
if(n == 2) return{0,1};
}
vector> edge(n,vector());
for(auto a : edges){
edge[a.first].push_back(a.second);
edge[a.second].push_back(a.first);
}
vector ret;
for(int i = 0;i < n;++ i) if(edge[i].size() == 1) ret.push_back(i);
int num = n;
while(num > 2){
for(;!ret.empty();ret.pop_back()){
int index1 = ret.back();
int index2 = edge[index1][0];
edge[index1].pop_back();
if(edge[index2].size() > 1)
edge[index2].erase(remove(edge[index2].begin(),edge[index2].end(),index1),edge[index2].end());
num -= 1;
}
for(int i = 0;i < n;++ i) if(edge[i].size() == 1) ret.push_back(i);
}
return ret;
}
};
- 313 Super Ugly Number
题意:给定素数列表,给出第n个这些素数可以组成的数字
思路:直接看代码吧,假如做不出来的话。。。
class Solution {
public:
int nthSuperUglyNumber(int n, vector& primes) {
int size = primes.size();
vector flag(size,0);
vector ret(n,1);
for(int i = 1;i < n;++ i){
int mini = INT_MAX;
for(int j = 0;j < size;++ j){
while(ret[i - 1] >= primes[j] * ret[flag[j]]) flag[j] ++;
mini = min(mini,primes[j] * ret[flag[j]]);
}
ret[i] = mini;
}
return ret[n - 1];
}
};
- 318 Maximum Product of Word Lengths
题意:无重复字母的单词的长度乘积最大值
思路:使用位运算作为map
class Solution {
public:
int maxProduct(vector& words) {
unordered_map maxlen;
for (string word : words) {
int mask = 0;
for (char c : word) mask |= 1 << (c - 'a');
maxlen[mask] = max(maxlen[mask], (int) word.size());
}
int result = 0;
for (auto a : maxlen) for (auto b : maxlen) if (!(a.first & b.first))
result = max(result, a.second * b.second);
return result;
}
};
- 319 Bulb Switcher
题意:关灯实验,第i次只操作i的整数的灯
思路:return sqrt(n)
- 322 Coin Change
题意:换硬币
思路:动态规划。。。刚开始想要用分治来做,但是思路非常混乱。。。对于动态规划的理解还是需要加强。。。
class Solution {
public:
int coinChange(vector& coins, int amount) {
int Max = amount + 1;
vector dp(amount + 1, Max);
dp[0] = 0;
for (int i = 1; i <= amount; i++) {
for (int j = 0; j < coins.size(); j++) {
if (coins[j] <= i) {
dp[i] = min(dp[i], dp[i - coins[j]] + 1);
}
}
}
return dp[amount] > amount ? -1 : dp[amount];
}
};
- 324 Wiggle Sort II(3)
题意:波浪排序
思路:找到中间值->序号重排、
class Solution {
public:
void wiggleSort(vector& nums) {
int size = nums.size();
auto midptr = nums.begin() + size / 2;
nth_element(nums.begin(), midptr, nums.end());
int mid = *midptr;
// cout< mid){
swap(A(index_odd ++), A(index ++));
}else if(A(index) < mid){
swap(A(index), A(index_even --));
}else{
index ++;
}
}
}
};
- 332 Reconstruct Itinerary(3)
题意:给出飞行顺序的最小字典结果
思路:比较新奇的分治法。
class Solution {
public:
vector findItinerary(vector> tickets) {
map> edge;
for(auto a : tickets) edge[a.first].insert(a.second);
vector ret;
divid(edge, ret, "JFK");
reverse(ret.begin(), ret.end());
return ret;
}
void divid(map>& edge, vector& ret, string s){
while(edge[s].size()){
string next = *edge[s].begin();
cout<
- 334 Increasing Triplet Subsequence
题意:判断数组中有没有三个升序数字
思路:啥也别说了,我是想不出来。。。不过还挺好理解的
class Solution {
public:
bool increasingTriplet(vector& nums) {
int imin = INT_MAX;
int imid = INT_MAX;
for(auto x : nums){
if(x <= imin) imin = x;
else if(x <= imid) imid = x;
else return true;
}
return false;
}
};
- 337 House Robber III
题意:有边的不能都遍历
思路:使用flag辅助
class Solution {
public:
int rob(TreeNode* root) {
return dfs(root, false);
}
int dfs(TreeNode* root, bool flag) {
if(!root) return 0;
if(flag) return dfs(root->left,false) + dfs(root->right,false);
else return max(root->val + dfs(root->left, true) + dfs(root->right, true),
dfs(root->left,false) + dfs(root->right,false));
}
};
- 338 Counting Bits
题意:返回前n个的二进制表示中1的个数的vector,要求one-pass
思路:简单的动态规划
class Solution {
public:
vector countBits(int num) {
vector ret(num + 1);
for(int i = 0;i <= num;++ i) ret[i] = ret[i >> 1] + (1 & i);
return ret;
}
};
- 341 Flatten Nested List Iterator