GitHub链接:https://github.com/WilliamWuLH/LeetCode
如果你觉得不错可以 ⭐Star 和 Fork ❤
121.Best Time to Buy and Sell Stock
维持一个最低价 + 一个最优解:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
int ans = 0, low = INT_MAX;
for(int i=0; i<len; i++){
low = min(low, prices[i]);
ans = max(ans, prices[i]-low);
}
return ans;
}
};
124.Binary Tree Maximum Path Sum
二叉树的后序遍历:
重点难点:
- 遍历到每一个结点,讨论该结点的最大路径和并且更新答案,在计算结点的最大路径和时需要考虑路径上有出现负数的情况,负数的路径就不要计算到最大路径和中。
- 返回包含该结点的最大路径和,最大路径和可以是该结点本身,或者是该结点和它的左子树最大路径和,也可以是该结点和它的右子树的最大路径和。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int maxPathSum(TreeNode* root) {
int ans = INT_MIN;
postorder(root, ans);
return ans;
}
int postorder(TreeNode* root, int &ans){
if(root == NULL)
return 0;
int lsum = postorder(root->left, ans);
int rsum = postorder(root->right, ans);
int pathcost = root->val;
pathcost = lsum > 0 ? pathcost + lsum : pathcost;
pathcost = rsum > 0 ? pathcost + rsum : pathcost;
ans = max(ans, pathcost);
return max(root->val, max(root->val + lsum, root->val + rsum));
}
};
128.Longest Consecutive Sequence
哈希表 + 判断:
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
map<int, int> hash;
int ans = 0;
for(auto i : nums)
hash[i] = 1;
for(auto i : hash){
if(! hash.count(i.first - 1)){
int cur = 1;
int thenum = i.first + 1;
while(hash.count(thenum)){
cur++;
thenum++;
}
ans = max(ans, cur);
}
}
return ans;
}
};
136.Single Number
先加后减:
出现一次就加上,再出现一次就减去,最后剩下的就是 Single Number。
class Solution {
public:
int singleNumber(vector<int>& nums) {
int len = nums.size();
int ans = 0;
map<int, int> m;
for(int i=0; i<len; i++){
if(m[ nums[i] ] == 0){
m[ nums[i] ] = 1;
ans += nums[i];
}
else
ans -= nums[i];
}
return ans;
}
};
位运算:
异或:a ^ 0 = a,a ^ a = 0
class Solution {
public:
int singleNumber(vector<int>& nums) {
int len = nums.size();
int ans = 0;
for(int i=0; i<len; i++){
ans ^= nums[i];
}
return ans;
}
};
139.Word Break
深度优先搜索 DFS:
时间复杂度太高。
动态规划:
相当于把字符串分为两个部分,前面的部分已经计算过是否可以由单词拼接而成,并且已经保存了结果,后面的部分即需要判断的单词,在单词集合里面找是否存在后面整个部分的单词。
i 表示现在需要判断的字符串长度(子字符串长度),j 表示现在需要判断的单词的开始位置。
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
int slen = s.length();
int wsize = wordDict.size();
int dp[slen+1];
dp[0] = 1;
for(int i=1; i<=slen; i++){
dp[i] = 0;
for(int j=0; j<i; j++){
if(dp[j]){
string temp = s.substr(j,i-j);
if(find(wordDict.begin(), wordDict.end(), temp) != wordDict.end()){
dp[i] = 1;
break;
}
}
}
}
return dp[slen] == 1;
}
};