Last updated on October 13, 2024 pm
                  
                
              
            
            
              
                
                k
2024/10/12
(1)贪心
在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。
思路:每个加油站的汽油数减去开往下一个加油站的消耗数,就是这一站能剩余的汽油数。如果加起来小于0就说明一定不能环路一周。如果可以,由于题目说开始的加油站的编号唯一,则到达那个加油站前,累计的剩余汽油数一定是最少的。否则这一站出发一定会到不了后面的某一站。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | class Solution {public:
 int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
 int n=gas.size(),cnt=0,min_g=0,ans=0;
 for(int i=0;i<n;i++){
 cnt+=gas[i]-cost[i];
 if(cnt<min_g){
 min_g=cnt;
 ans=i+1;
 }
 }
 return cnt<0?-1:ans;
 }
 };
 
 | 
n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到 1个糖果。
- 相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
需要考虑两边!!!!
这个思路很简单聪明:就是维护两个数组分别代表从左、右遍历后每个人分发的糖果数。起始每个人糖果数均为1,如果大于前一个人的糖果数,则比前一个人多一个。最后比较左右遍历的数组中每个小孩的糖果数,较大的那个值才能满足条件。这样累加起来是满足条件并且需要准备的糖果最少。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | class Solution {public:
 int candy(vector<int>& ratings) {
 int n=ratings.size();
 vector<int> left(n,1),right(n,1);
 int cnt=0;
 for(int i=1;i<n;i++)
 if(ratings[i]>ratings[i-1])
 left[i]=left[i-1]+1;
 for(int i=n-2;i>=0;i--){
 if(ratings[i]>ratings[i+1]){
 right[i]=right[i+1]+1;
 }
 cnt+=max(left[i],right[i]);
 }
 return cnt+max(left[n-1],right[n-1]);
 }
 };
 
 | 
(2)广度优先搜索
你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。
在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。
- 例如,先修课程对 [0, 1]表示:想要学习课程0,你需要先完成课程1。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 
 | class Solution {public:
 bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
 vector<int> step(numCourses,0);
 unordered_map<int,vector<int> > map;
 int cnt=0;
 
 for(auto pre:prerequisites){
 step[pre[0]]++;
 map[pre[1]].push_back(pre[0]);
 }
 
 queue <int> zero;
 for(int i=0;i<numCourses;i++)
 if(!step[i])
 zero.push(i);
 
 while(!zero.empty()){
 int select=zero.front();
 zero.pop();
 cnt++;
 for(int cur: map[select]){
 if(--step[cur]==0)
 zero.push(cur);
 }
 }
 return cnt==numCourses;
 }
 };
 
 | 
(3)回溯
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下(与电话按键相同)。注意 0、1 不对应任何字母。
注意:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 
 | class Solution {
 string MAPPING[10] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
 
 
 void dfs(const string& digits, int i, string& path, vector<string>& ans) {
 if (i == digits.length()) {
 ans.emplace_back(path);
 return;
 }
 for (char c : MAPPING[digits[i] - '0']) {
 path[i] = c;
 dfs(digits, i + 1, path, ans);
 }
 }
 
 public:
 vector<string> letterCombinations(string digits) {
 int n = digits.length();
 if (n == 0) {
 return {};
 }
 vector<string> ans;
 string path(n, 0);
 dfs(digits, 0, path, ans);
 return ans;
 }
 };
 
 | 
()?
给一个数组,只含有0或者1,求最大的连续的0的个数;注意:有一次机会可以将数字翻转(1变成0,或者0变成1)。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 
 | int findMaxConsecutiveZeros(vector<int>& nums) {int maxCount = 0;
 int zeroCount = 0;
 int flipZeroCount = 0;
 
 for (int i = 0; i < nums.size(); ++i) {
 if (nums[i] == 0) {
 zeroCount++;
 flipZeroCount++;
 } else {
 
 flipZeroCount = zeroCount + 1;
 zeroCount = 0;
 }
 maxCount = max(maxCount, flipZeroCount);
 }
 
 return maxCount;
 }
 
 |