LeetCode刷题记录 16-20

马上要面试了,把前些天在LeetCode上刷的题再看一遍。

写上注释,算复习了,也方便以后复习。

带 * 号的为忘记怎么做的。

16. 121. 买卖股票的最佳时机(简单优化)

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        if (n == 0) return 0;
        int minPrice = prices[0];
        int ans = 0;
        // 只需要遍历一遍的做法
        for (int i = 1; i < n; i++) {
            // 发现更优答案,则当前价格一定大于之前的最小价格
            if (prices[i] - minPrice > ans) ans = prices[i] - minPrice;
            // 否则,看看能不能更新一下最小价格,以便之后获得更优答案
            else if (prices[i] < minPrice) minPrice = prices[i];
        }
        return ans;
    }
};
/*
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        if (n == 0) return 0;
        // 需要遍历三遍
        vector<int> left(n), right(n);
        // left[i]存第0到第i天价格的最低值
        left[0] = prices[0];
        for (int i = 1; i < n; i++) {
            left[i] = min(prices[i], left[i - 1]);
        }
        // right[i]存第n-1到第i天价格的最高值
        right[n - 1] = prices[n - 1];
        for (int i = n - 2; i >= 0; i--) {
            right[i] = max(prices[i], right[i + 1]);
        }
        // 寻找最优值,对非递增序列也有效
        int ans = 0;
        for (int i = 0; i < n; i++) {
            ans = max(ans, right[i] - left[i]);
        }
        return ans;
    }
};
*/

17. 42. 接雨水(数组优化)

class Solution {
public:
    int trap(vector<int>& height) {
        // 遍历三遍数组
        int n = height.size();
        if (n == 0) return 0;
        vector<int> left_max(n), right_max(n);
        // left[i]存从0到i的最大值
        left_max[0] = height[0];
        for (int i = 1; i < n; i++) left_max[i] = max(left_max[i-1], height[i]);
        // right[i]存从n-1到i的最大值
        right_max[n-1] = height[n-1];
        for (int i = n - 2; i >= 0; i--) right_max[i] = max(right_max[i+1], height[i]);
        // 寻找答案,每个位置能存的水的量为两边最大值较小的减去高度
        int ans = 0;
        for (int i = 0; i < n; i++) ans += (min(left_max[i], right_max[i]) - height[i]);
        return ans;
    }
};

18. 53. 最大子序和(动态规划)

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int n = nums.size();
        if (n == 0) return 0;
        vector<int> dp(n);
        // dp[i]记录以i位置为结尾的最大子序列和
        dp[0] = nums[0];
        for (int i = 1; i < n; i++) {
            // 老题了,动态规划的状态转移
            if (dp[i-1] < 0) dp[i] = nums[i];
            else dp[i] = dp[i-1] + nums[i];
        }
        // 再遍历一遍找到最值
        int ans = dp[0];
        for (int i = 1; i < n; i++) {
            ans = max(ans, dp[i]);
        }
        return ans;
    }
};

19. 20. 有效的括号(栈模拟)

class Solution {
public:
    // 是否是右括号
    bool isRight(char ch) {
        return (ch == ')' || ch == ']' || ch == '}');
    }
    // 是否是配套括号
    bool isOK(char ch1, char ch2) {
        return (ch1 == '(' && ch2 == ')' || ch1 == '[' && ch2 == ']' || ch1 == '{' && ch2 == '}');
    }

    bool isValid(string s) {
        int len = s.length();
        stack<char> stk;
        for (int i = 0; i < len; i++) {
            char ch = s[i];
            // 右括号需要进行判断与处理
            if (isRight(ch)) {
                // 如果为空,则不配套,返回false
                if (stk.empty()) return false;
                char temp = stk.top();
                // 否则,如果配套,弹出左括号
                if (isOK(temp, ch)) {
                    stk.pop();
                }
                // 不配套就返回false
                else {
                    return false;
                }
            }
            // 左括号直接压入
            else {
                stk.push(ch);
            }
        }
        return stk.empty();
    }
};

20. 15. 三数之和(对撞指针)

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int n = nums.size();
        sort(nums.begin(), nums.end());
        vector< vector<int> > ans;
        for (int i = 0; i < n - 2; i++) {
            if (nums[i] > 0) break;  // 不可能再等于0了
            if (i > 0 && nums[i] == nums[i - 1]) continue; // 去重
            int l = i + 1, r = n - 1; // 对撞指针
            while (l < r) {
                int sum = nums[i] + nums[l] + nums[r];
                if (sum == 0) {
                    vector<int> v;
                    v.push_back(nums[i]);
                    v.push_back(nums[l]);
                    v.push_back(nums[r]);
                    ans.push_back(v);
                    while (l < r && nums[l] == nums[l + 1]) l++; // 去重
                    while (l < r && nums[r] == nums[r - 1]) r--; // 去重
                    l++;
                    r--; 
                }
                else if (sum < 0) l++;
                else r--;
            }
        }
        return ans;
    }
};
发布了110 篇原创文章 · 获赞 26 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/liujh_990807/article/details/104078527