代码随想录leetcode200题之贪心算法

1 介绍

本博客用来记录代码随想录leetcode200题之贪心算法相关题目。

2 训练

题目1455. 分发饼干

C++代码如下,

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        sort(g.begin(), g.end());
        sort(s.begin(), s.end());
        int res = 0;
        for (auto x : s) {
            if (res < g.size() && x >= g[res]) {
                res += 1;
            }
        }
        return res;
    }
};

python3代码如下,

class Solution:
    def findContentChildren(self, g: List[int], s: List[int]) -> int:
        g.sort()
        s.sort()
        res = 0
        for x in s:
            if res < len(g) and x >= g[res]:
                res += 1
        return res 

题目2376. 摆动序列

C++代码如下,

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int n = nums.size();
        vector<int> diff;
        for (int i = 0; i < n-1; ++i) {
            diff.emplace_back(nums[i+1]-nums[i]);
        }
        int res = 0;
        int prex = -2010;
        for (auto x : diff) {
            if (x == 0) prex += x;
            else if (prex == -2010 || prex * x < 0) {
                res += 1;
                prex = x;
            } else prex += x;
        }
        return res + 1;
    }
};

python3代码如下,

class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        n = len(nums)
        diff = []
        for i in range(n-1):
            diff.append(nums[i+1]-nums[i])
        res = 0
        pre = -2010
        for x in diff:
            if x == 0:
                pre += x
            elif pre == -2010 or pre * x < 0:
                res += 1
                pre = x 
            else:
                pre += x
        return res + 1

题目353. 最大子数组和

C++代码如下,

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int res = -1e5;
        int cur = 0;
        for (auto x : nums) {
            if (cur <= 0) cur = x;
            else cur += x;
            res = max(res, cur);
        }
        return res;
    }
};

python3代码如下,

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        res = int(-1e5)
        cur = 0
        for x in nums:
            if cur <= 0:
                cur = x
            else:
                cur += x
            res = max(res, cur)
        return res

题目4122. 买卖股票的最佳时机 II

C++代码如下,

贪心写法,

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        vector<int> diff;
        for (int i = 0; i < n-1; ++i) {
            diff.emplace_back(prices[i+1]-prices[i]);
        }
        int res = 0;
        for (auto x : diff) {
            if (x > 0) res += x;
        }
        return res;
    }
};

动态规划写法,

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        vector<vector<int>> dp(n, vector<int>(2, 0));
        //状态定义
        //dp[i][0]:第i天不持股的最大现金
        //dp[i][1]:第i天持股的最大现金
        //状态转移
        //dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
        //dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
        //状态初始化
        //dp[0][0] = 0
        //dp[0][1] = -prices[0]
        dp[0][1] = -prices[0];
        for (int i = 1; i < n; ++i) {
            dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]);
            dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i]);
        }
        return dp[n-1][0];
    }
};

python3代码如下,

贪心写法,

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        diff = []
        for i in range(n-1):
            diff.append(prices[i+1]-prices[i])
        res = 0
        for x in diff:
            if x > 0:
                res += x
        return res

动态规划写法,

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        dp = [[0, 0] for _ in range(n)]
        #状态定义
        #dp[i][0]: 第i天不持股的最大现金
        #dp[i][1]: 第i天持股的最大现金
        #状态转移
        #dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
        #dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
        #状态初始化
        #dp[0][0] = 0
        #dp[0][1] = -prices[0]
        dp[0][1] = -prices[0]
        for i in range(1,n):
            dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
            dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
        return dp[n-1][0]

题目555. 跳跃游戏

C++代码如下,

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int n = nums.size();
        int cover = 0;
        for (int i = 0; i <= cover; ++i) {
            cover = max(cover, nums[i]+i);
            if (cover >= n-1) return true;
        }
        return false;
    }
};

python3代码如下,

class Solution:
    def canJump(self, nums: List[int]) -> bool:
        n = len(nums)
        cover = 0
        i = 0
        while i <= cover:
            cover = max(nums[i] + i, cover)
            if cover >= n-1:
                return True
            i += 1
        return False 

题目645. 跳跃游戏 II

C++代码如下,

class Solution {
public:
    int jump(vector<int>& nums) {
        int n = nums.size();
        int res = 0;
        int i = 0;
        while (i < n-1) {
            if (i + nums[i] >= n-1) {
                res += 1;
                return res;
            }
            int t = i + 1;
            for (int j = i+1; j <= i+nums[i]; ++j) {
                if (t + nums[t] < j + nums[j]) {
                    t = j;
                }
            }
            res += 1;
            i = t; //更新i
        }
        return res;
    }
};

python3代码如下,

class Solution:
    def jump(self, nums: List[int]) -> int:
        n = len(nums)
        res = 0
        i = 0
        while i < n-1:
            if i + nums[i] >= n - 1:
                res += 1
                break
            length = nums[i]
            #[i+1,i+length]
            t = i + 1
            for j in range(i+1,i+length+1):
                if nums[t] + t < nums[j] + j:
                    t = j 
            res += 1
            i = t #更新i
        return res 

题目71005. K 次取反后最大化的数组和

C++代码如下,

class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        int n = nums.size();
        sort(nums.begin(), nums.end(), [](int x, int y) {
            return abs(x) > abs(y);
        });
        for (int i = 0; i < n; ++i) {
            if (k > 0 && nums[i] < 0) {
                nums[i] *= -1;
                k -= 1;
            } 
        }
        if (k % 2 == 1) {
            nums[n-1] *= -1;
        }
        return accumulate(nums.begin(), nums.end(), 0);
    }
};

python3代码如下,

class Solution:
    def largestSumAfterKNegations(self, nums: List[int], k: int) -> int:
        n = len(nums)
        nums.sort(key = lambda x : abs(x), reverse = True)
        for i in range(n):
            if k > 0 and nums[i] < 0:
                nums[i] *= -1
                k -= 1
        if k % 2 == 1:
            nums[-1] *= -1
        return sum(nums)

题目8134. 加油站

C++代码如下,

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int n = gas.size();
        int currSum = 0;
        int totalSum = 0;
        int res = 0;
        for (int i = 0; i < n; ++i) {
            int t = gas[i] - cost[i];
            if (currSum < 0) {
                currSum = 0;
                res = i;
            }
            currSum += t;
            totalSum += t;
        }
        if (totalSum < 0) res = -1;
        return res;
    }
};

python3代码如下,

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        totalSum = 0
        curSum = 0
        n = len(gas)
        res = 0
        for i in range(n):
            t = gas[i] - cost[i]
            if curSum < 0:
                curSum = 0
                res = i
            curSum += t
            totalSum += t
        if totalSum < 0:
            res = -1
        return res

题目9135. 分发糖果

C++代码如下,

class Solution {
public:
    int candy(vector<int>& ratings) {
        int n = ratings.size();
        vector<int> nums(n, 1);
        for (int i = 1; i < n; ++i) {
            if (ratings[i] > ratings[i-1]) {
                nums[i] = nums[i-1] + 1;
            }
        }
        for (int i = n-2; i >= 0; --i) {
            if (ratings[i] > ratings[i+1]) {
                nums[i] = max(nums[i], nums[i+1] + 1);
            }
        }
        return accumulate(nums.begin(), nums.end(), 0);
    }
};

python3代码如下,

class Solution:
    def candy(self, ratings: List[int]) -> int:
        n = len(ratings)
        nums = [1] * n 
        for i in range(1,n):
            if ratings[i] > ratings[i-1]:
                nums[i] = nums[i-1] + 1
        for i in range(n-2,-1,-1):
            if ratings[i] > ratings[i+1]:
                nums[i] = max(nums[i], nums[i+1] + 1)
        return sum(nums)

题目10860. 柠檬水找零

C++代码如下,

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        vector<int> cur = {0, 0, 0};
        //cur[0]表示5元纸币的数目
        //cur[1]表示10元纸币的数目
        //cur[2]表示20元纸币的数目
        for (auto x : bills) {
            if (x == 5) {
                cur[0] += 1;
            } else if (x == 10) {
                cur[0] -= 1;
                cur[1] += 1;
                if (cur[0] < 0) return false;
            } else {
                if (cur[1] > 0) {
                    cur[1] -= 1;
                    cur[0] -= 1;
                } else {
                    cur[0] -= 3;
                }
                if (cur[0] < 0 || cur[1] < 0) return false;
                cur[2] += 1;
            }
        }
        return true;
    }
};

python3代码如下,

class Solution:
    def lemonadeChange(self, bills: List[int]) -> bool:
        cur = [0, 0, 0]
        #cur[0]表示5元纸币的数目
        #cur[1]表示10元纸币的数目
        #cur[2]表示20元纸币的数目
        for x in bills:
            if x == 5:
                cur[0] += 1
            elif x == 10:
                cur[0] -= 1
                if cur[0] < 0:
                    return False
                cur[1] += 1
            else:
                if cur[1] > 0:
                    cur[1] -= 1
                    cur[0] -= 1
                else:
                    cur[0] -= 3
                if cur[0] < 0 or cur[1] < 0:
                    return False
                cur[2] += 1
        return True

题目11406. 根据身高重建队列

C++代码如下,

class Solution {
public:
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(), people.end(), [](vector<int> a, vector<int> b) {
            return a[0] > b[0] || (a[0] == b[0] && a[1] < b[1]); 
        });
        vector<vector<int>> res;
        for (auto x : people) {
            int idx = x[1];
            res.insert(res.begin() + idx, x);
        }
        return res;
    }
};

python3代码如下,

class Solution:
    def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
        people.sort(key = lambda x : (x[0],-x[1]), reverse = True)
        res = []
        for x in people:
            i = x[1]
            res.insert(i, x)
        return res

题目12452. 用最少数量的箭引爆气球

C++代码如下,

class Solution {
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        int n = points.size();
        sort(points.begin(), points.end());
        if (n == 0) { //特判
            return 0;
        }
        int res = 1;
        for (int i = 1; i < n; ++i) {
            if (points[i][0] > points[i-1][1]) {
                res += 1;
            } else {
                points[i][1] = min(points[i][1], points[i-1][1]);
            }
        }
        return res;
    }
};

python3代码如下,

class Solution:
    def findMinArrowShots(self, points: List[List[int]]) -> int:
        n = len(points)
        points.sort()
        if n == 0: #特判
            return 0
        res = 1
        for i in range(1,n):
            if points[i][0] > points[i-1][1]:
                res += 1
            else:
                points[i][1] = min(points[i][1], points[i-1][1])
        return res

题目13435. 无重叠区间

C++代码如下,

class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        sort(intervals.begin(), intervals.end());
        int n = intervals.size();
        int res = 0;
        for (int i = 1; i < n; ++i) {
            if (intervals[i][0] < intervals[i-1][1]) {
                res += 1;
                intervals[i][1] = min(intervals[i][1], intervals[i-1][1]);
            }
        }
        return res;
    }
};

python3代码如下,

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        intervals.sort()
        n = len(intervals)
        res = 0
        for i in range(1,n):
            if intervals[i][0] < intervals[i-1][1]:
                intervals[i][1] = min(intervals[i][1], intervals[i-1][1])
                res += 1
        return res

题目14763. 划分字母区间

C++代码如下,

class Solution {
public:
    vector<int> partitionLabels(string s) {
        int n = s.size();
        unordered_map<char, int> map_c_ei;
        for (int i = 0; i < n; ++i) {
            map_c_ei[s[i]] = i;
        }
        int left = 0, right = 0;
        vector<int> res;
        for (int i = 0; i < n; ++i) {
            right = max(right, map_c_ei[s[i]]);
            if (i == right) {
                res.emplace_back(right-left+1);
                left = right + 1;
            }
        }
        return res;
    }
};

python3代码如下,

Carl哥写法,

class Solution:
    def partitionLabels(self, s: str) -> List[int]:
        map_c_ei = collections.defaultdict(int)
        n = len(s)
        for i in range(n):
            map_c_ei[s[i]] = i 
        res = []
        left = 0
        right = 0
        for i in range(n):
            right = max(right, map_c_ei[s[i]])
            if i == right:
                res.append(right-left+1)
                left = right + 1
        return res

区间解法,

class Solution:
    def partitionLabels(self, s: str) -> List[int]:
        n = len(s)
        map_c_si = collections.defaultdict(int)
        map_c_ei = collections.defaultdict(int)
        for i in range(n):
            map_c_ei[s[i]] = i 
        for i in range(n-1,-1,-1):
            map_c_si[s[i]] = i 
        intervals = []
        for i in range(26):
            c = chr(ord('a') + i)
            if c in map_c_si:
                si = map_c_si[c]
                ei = map_c_ei[c]
                intervals.append([si,ei])
        
        intervals.sort()
        m = len(intervals)
        res = []
        i, j = intervals[0][0], intervals[0][1]
        for k in range(1,m):
            ni = intervals[k][0]
            nj = intervals[k][1]
            if ni > j:
                res.append([i,j])
                i, j = ni, nj 
            else:
                j = max(j, nj)
        res.append([i,j])
        newres = []
        for interval in res:
            newres.append(interval[1] - interval[0] + 1)
        return newres 
        

题目1556. 合并区间

C++代码如下,

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        int n = intervals.size();
        sort(intervals.begin(), intervals.end());
        int i = intervals[0][0], j = intervals[0][1];
        vector<vector<int>> res;
        for (int k = 1; k < n; ++k) {
            int ni = intervals[k][0];
            int nj = intervals[k][1];
            if (ni > j) {
                res.emplace_back(vector<int>{i,j});
                i = ni;
                j = nj;
            } else {
                j = max(j, nj);
            }
        }
        res.emplace_back(vector<int>{i,j});
        return res;
    }
};

python3代码如下,

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        intervals.sort()
        n = len(intervals)
        res = []
        i = intervals[0][0]
        j = intervals[0][1]
        for k in range(1,n):
            ni, nj = intervals[k][0], intervals[k][1]
            if ni > j:
                res.append([i,j])
                i, j = ni, nj
            else:
                j = max(j, nj)
        res.append([i,j])
        return res  

题目16738. 单调递增的数字

C++代码如下,

class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        string s = to_string(n);
        n = s.size();
        int j = n;
        for (int i = n-2; i >= 0; --i) {
            if (s[i] > s[i+1]) {
                j = i + 1;
                s[i] -= 1;
            }
        }
        for (int i = j; i < n; ++i) {
            s[i] = '9';
        }
        return stoi(s);
    }
};

python3代码如下,

class Solution:
    def monotoneIncreasingDigits(self, n: int) -> int:
        s = str(n)
        nums = list(s)
        n = len(nums)
        j = n
        for i in range(n-2,-1,-1):
            if nums[i] > nums[i+1]:
                nums[i] = chr(ord(nums[i]) - 1)
                j = i + 1
        for i in range(j, n):
            nums[i] = '9'
        t = "".join(nums)
        return int(t)

题目17968. 监控二叉树

C++代码如下,

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int minCameraCover(TreeNode* root) {
        int res = 0;
        //结点的状态
        //0:表示结点没有被覆盖
        //1:表示结点被覆盖,且有照相机
        //2:表示结点被覆盖,但没有照相机
        function<int(TreeNode*)> dfs =[&] (TreeNode *node) -> int {
            //后序遍历,左右根
            if (node == nullptr) return 2;
            int left = dfs(node->left);
            int right = dfs(node->right);
            //当前结点处理逻辑
            if (left == 2 && right == 2) return 0;
            if (left == 0 || right == 0) {
                res += 1;
                return 1;
            }
            if (left == 1 || right == 1) return 2;
            return -1;
        };
        if (dfs(root) == 0) res += 1;
        return res;
    }
};

python3代码如下,

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def minCameraCover(self, root: Optional[TreeNode]) -> int:
        res = 0
        #结点的状态
        #0:该结点未被覆盖
        #1:该结点被覆盖,且有照相机
        #2:该结点被覆盖,但没有照相机
        def dfs(node: TreeNode) -> int:
            nonlocal res
            #后序遍历,左右根
            if node is None:
                return 2
            left = dfs(node.left)
            right = dfs(node.right)
            #处理逻辑
            if left == 2 and right == 2:
                return 0
            if left == 0 or right == 0:
                res += 1
                return 1
            if left == 1 or right == 1:
                return 2
            return -1
        if dfs(root) == 0:
            res += 1
        return res

3 参考

代码随想录官网

  • 14
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YMWM_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值