LeetCode题解-05(搜索、贪心)

LeetCode题解

chap-13:搜索

section13-1: DFS

1、电话号码的字母组合

class Solution {
public:
    vector<string> dict = {"","","abc","def","ghi","jkl","mno",
                           "pqrs","tuv","wxyz"};
    vector<string> res;
    vector<string> letterCombinations(string digits) {
        if(digits.empty()) return res;
        dfs(digits,0,"");
        return  res;
    }
    void dfs(string& digits,int u,string path){
        if(u == digits.size()) res.push_back(path);
        else
            for(auto &c:dict[digits[u] - '0']){
                dfs(digits,u+1,path + c);
            }
    }
};

2、括号生成

class Solution {
public:
    vector<string> res;
    vector<string> generateParenthesis(int n) {
        dfs(n,0,0,"");
        return res;
    }
    void dfs(int n,int lc, int rc, string s){
        if(lc == n && rc == n) {res.push_back(s);return;}
        if(lc < n) dfs(n,lc+1,rc,s+'(');
        if(rc < lc && rc < n) dfs(n,lc,rc+1,s+')');
    }
};

3、解数独

class Solution {
public:
    bool col[9][9];
    bool row[9][9];
    bool cell[3][3][9];
    void solveSudoku(vector<vector<char>>& board) {
        memset(row, 0, sizeof row);
        memset(col, 0, sizeof col);
        memset(cell, 0, sizeof cell);
        for (int i = 0; i < 9; i ++ )
            for (int j = 0; j < 9; j ++ )
                if (board[i][j] != '.') {
                    int t = board[i][j] - '1';
                    row[i][t] = col[j][t] = cell[i / 3][j / 3][t] = true;
                }

        dfs(board,0,0);
    }
    bool dfs(vector<vector<char>>&board,int x,int y){
        if (y == 9) x ++, y = 0;
        if (x == 9) return true;
        if (board[x][y] != '.') return dfs(board, x, y + 1);
        for (int i = 0; i < 9; i ++ )
            if (!row[x][i] && !col[y][i] && !cell[x / 3][y / 3][i]) {
                board[x][y] = '1' + i;
                row[x][i] = col[y][i] = cell[x / 3][y / 3][i] = true;
                if (dfs(board, x, y + 1)) return true;
                board[x][y] = '.';
                row[x][i] = col[y][i] = cell[x / 3][y / 3][i] = false;
            }

        return false;
    }
};

4、组合总和

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    vector<vector<int>> combinationSum(vector<int>& cs, int t) {
        dfs(cs,0,t);
        return ans;
    }
    void dfs(vector<int>& cs, int u,int t){
        if(!t) {ans.push_back(path); return;}
        for(int i=u;i<cs.size();i++){
            if(t - cs[i] < 0) continue;
            else{
                path.push_back(cs[i]);
                dfs(cs,i,t-cs[i]);
                path.pop_back();
            }
        }
    }
};

5、组合总和 II【×】

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    vector<vector<int>> combinationSum2(vector<int>& cs, int t) {
        sort(cs.begin(), cs.end());
        dfs(cs,0,t);
        return ans;
    }
    void dfs(vector<int>& cs,int u,int t){
        if(t==0) {ans.push_back(path); return;}
        if(u == cs.size()) return;
        int len = u;
        while(len<cs.size() && cs[len] == cs[u]) len++;
        for(int i=0;i*cs[u] <= t && i<=len-u;i++){            
            dfs(cs,len,t-cs[u]*i); // 先置因i=0
            path.push_back(cs[u]);
        }
        for(int i=0;i*cs[u] <= t && i<=len-u;i++)
            path.pop_back();
    }
};

// other
class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    vector<vector<int>> combinationSum2(vector<int>& cs, int t) {
        sort(cs.begin(),cs.end());
        dfs(cs,0,t);
        return ans;
    }

    void dfs(vector<int>& cs,int u,int t){
        if(!t){ans.push_back(path); return;}
        if(u == cs.size()) return;
        for(int i=u;i<cs.size();i++){            
            if(t-cs[u] >= 0){
                if(i>u && cs[i-1] == cs[i]) continue; // 去重
                path.push_back(cs[i]);
                dfs(cs,i+1,t-cs[i]);
                path.pop_back();
            }
        }
    }
};

6、组合总和 III

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    int cs[9] = {1,2,3,4,5,6,7,8,9};
    int k;
    vector<vector<int>> combinationSum3(int k_, int t) {
        k = k_;
        dfs(0,0,t);
        return ans;
    }
    void dfs(int start,int u,int t){
        if(!t && u == k) {ans.push_back(path); return;}
        if(start > 9) return;
        for(int i=start;i<9;i++){
            if(t-cs[i] >= 0){
                path.push_back(cs[i]);
                dfs(i+1,u+1,t-cs[i]);
                path.pop_back();
            }
        }
    }
};

7、全排列

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    vector<bool> f;
    vector<vector<int>> permute(vector<int>& nums) {
        f = vector<bool>(nums.size(),false);
        dfs(nums);
        return ans;
    }
    void dfs(vector<int>&nums){
        if(path.size() == nums.size()) {
            ans.push_back(path); return;
        }
        for(int i=0;i<nums.size();i++){
            if(f[i] == false){
                f[i] = true;
                path.push_back(nums[i]);
                dfs(nums);
                path.pop_back();
                f[i] = false;
            }
        }
    }
};

8、全排列 II

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    vector<bool> f;
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        f = vector<bool>(nums.size(),false);
        path = vector<int>(nums.size());
        sort(nums.begin(),nums.end());
        dfs(nums,0);
        return ans;
    }
    void dfs(vector<int>&nums,int idx){
        if(idx == nums.size()) ans.push_back(path);
        else{
            for(int i=0;i<nums.size();i++){
                if(f[i] || (i && nums[i-1] == nums[i] && f[i-1] == false)) continue;
                f[i] = true;
                path[idx] = nums[i];
                dfs(nums, idx+1);
                f[i] = false;
            }
        }
    }
};

9、N 皇后

class Solution {
public:
    vector<string> path;
    vector<vector<string>> ans;
    vector<bool> col;
    vector<bool> dig, anti_dig;
    vector<vector<string>> solveNQueens(int n) {
        path = vector<string>(n,string(n,'.'));
        col = vector<bool>(n,false);
        dig = anti_dig = vector<bool>(2*n,false);
        dfs(0, n);
        return ans;
    }
    void dfs(int u, int n){
        if(u == n) ans.push_back(path);
        else
            for(int i=0;i<n;i++){
                if(!col[i] && !dig[i+u] && !anti_dig[i-u+n]){
                    col[i] = dig[i+u]= anti_dig[i-u+n] = true;
                    path[u][i] = 'Q';
                    dfs(u+1, n);
                    path[u][i] = '.';
                    col[i] = dig[i+u]= anti_dig[i-u+n] = false;
                }
            }
    }
};

10、N皇后 II

class Solution {
public:
    vector<bool> col,dig,vdig;
    int res = 0;
    int totalNQueens(int n) {
        col = vector<bool>(n);
        dig = vdig = vector<bool>(2*n);
        dfs(0,n);
        return res;
    }
    void dfs(int row,int n){
        if(row == n) res+=1;
        else{
            for(int j = 0;j<n;j++){
                if(col[j] || dig[j+row] || vdig[row + n - j]) continue;
                else{
                    col[j] = dig[j + row] = vdig[row + n -j] = true;
                    dfs(row + 1,n);
                    col[j] = dig[j + row] = vdig[row + n -j] = false;
                }
            }
        }
    }
};

11、组合

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    vector<vector<int>> combine(int n, int k) {
        dfs(1,n,k);
        return ans;
    }
    void dfs(int u,int n,int k){
        if(path.size() == k) ans.push_back(path);
        else{
            for(int i=u;i<=n;i++) {
                path.push_back(i);
                dfs(i+1,n,k);
                path.pop_back();
            }
        }
    }
};

12、子集【×】

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    vector<vector<int>> subsets(vector<int>& nums) {
        dfs(nums, 0);
        return ans;
    }
    void dfs(vector<int>& nums, int u){
        if(u == nums.size()) ans.push_back(path);
        else{
            path.push_back(nums[u]);
            dfs(nums,u+1);
            path.pop_back();
            dfs(nums,u+1);
        }
    }
};

// 二进制位表示 取与不取
class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> ans;
        int n = nums.size();
        for(int i=0;i<(1<<n);i++){
            vector<int> temp;
            for(int j=0;j<n;j++)
                if(i>>j & 1) temp.push_back(nums[j]);
            ans.push_back(temp);
        }
        return ans;
    }
};

13、子集 II

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        dfs(nums,0);
        return ans;
    }
    void dfs(vector<int>&nums, int u){
        if(u == nums.size()) ans.push_back(path);
        else{
            int k = u;
            while(k<nums.size() && nums[k] == nums[u])k++;
            for(int i=0;i<=k-u;i++){
                dfs(nums,k);
                path.push_back(nums[u]);
            }
            for(int i=0;i<=k-u;i++) path.pop_back();
        }
    }
};

// 计数易懂
class Solution {
public:
    vector<vector<int>> ans;
    vector<int> path;
    unordered_map<int,int> hash;
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        for(auto &a:nums) hash[a]++; // 记录数集总数
        dfs(-10);
        return ans;
    }
    void dfs(int u){
        if(u > 10) ans.push_back(path);
        else{
            for(int i=0;i<hash[u]+1;i++){
                dfs(u+1);
                path.push_back(u);
            }
            for(int i=0;i<hash[u]+1;i++) path.pop_back();
        }
    }
};

14、单词搜索

class Solution {
public:
    string word;
    int col[4] = {-1,0,1,0};
    int row[4] = {0,-1,0,1};
    bool ans = false;
    bool exist(vector<vector<char>>& board, string word_) {
        word = word_;
        for(int x=0;x<board.size();x++)
            for(int y=0;y<board[0].size();y++)
                if(board[x][y] == word[0]){
                    board[x][y] = '.';
                    dfs(board,x,y,1);
                    if(ans) return ans;
                    board[x][y] = word[0];
                }
        return ans;
    }
    void dfs(vector<vector<char>>&board,int x,int y,int s){
        if(s == word.size()) ans = true;
        else
            for(int i=0;i<4;i++){
                int dx = row[i]+x, dy = col[i]+y;
                if(dx>=0 && dx<board.size() && dy>=0 && dy<board[0].size() && board[dx][dy] == word[s]){
                    board[dx][dy] = '.';
                    dfs(board,dx,dy,s+1);
                    board[dx][dy] = word[s];
                }
            }
        }
};

15、复原 IP 地址

class Solution {
public:
    vector<string> ans;
    vector<int> path;
    vector<string> restoreIpAddresses(string s) {
        dfs(s,0,0);
        return ans;
    }
    void dfs(string&s,int u,int tot){
        if(u == s.size()){
           if(tot == 4){
               string p;
               for(auto t:path) p+=to_string(t)+'.';
               p.pop_back(); ans.push_back(p);
           }
           return;
        }
        if(tot > 4) return;
        int t = 0;
        for(int i=u;i<s.size();i++){
            t = t*10 + s[i]-'0';
            if(t>=0 && t<256){
                path.push_back(t);
                dfs(s,i+1,tot+1);
                path.pop_back();
            }else break;
            if(!t) break;
        }
    }
};

16、被围绕的区域

class Solution {
public:
    vector<vector<char>> board;
    int m,n;
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
    void solve(vector<vector<char>>& board1) {
        board = board1;
        n = board.size(); m = board[0].size();
        for(int i = 0;i<n;i++){ // 逆向思维
            if(board[i][0] == 'O' ) dfs(i,0);            
            if(board[i][m-1] == 'O') dfs(i,m-1);
        }
        for(int i = 0;i<m;i++){
            if(board[0][i] == 'O') dfs(0,i);
            if(board[n-1][i] == 'O') dfs(n-1,i);
        }
        for(int i = 0;i<n;i++)
            for(int j = 0;j<m;j++) 
                if(board[i][j] == '#') board[i][j] = 'O';
                else board[i][j] = 'X';
        board1 = board;
    }

    void dfs(int a,int b){
        board[a][b] = '#';
        for(int i = 0;i<4;i++){
            int x = a + dx[i], y = b + dy[i];
            if(x>=0 && x <n && y >=0 && y<m && board[x][y] == 'O')
                dfs(x,y);
        }
    }
};

17、克隆图

class Solution {
public:
    unordered_map<Node*,Node*> hash;
    Node* cloneGraph(Node* node) {
        if(!node) return NULL;
        dfs(node);
        for(auto [s,t]:hash){
            for(auto neb:s->neighbors)
                t->neighbors.push_back(hash[neb]);
        }
        return hash[node];
    }
    void dfs(Node* node){
        hash[node] = new Node(node->val);
        for(auto neb:node->neighbors){
            if(!hash.count(neb))
                dfs(neb);
        }
    }
};

18、复制带随机指针的链表

class Solution {
public:
    unordered_map<Node*,Node*> hash;
    Node* copyRandomList(Node* head) {
        if(head == NULL) return NULL;
        dfs(head);
        for(auto [s,d]:hash){
            d->next = s->next ? hash[s->next] : NULL;
            d->random = s->random ? hash[s->random] : NULL;
        }
        return hash[head];
    }
    void dfs(Node* h){
        if(h) {
            hash[h] = new Node(h->val);
            h = h->next;
            dfs(h);
        }
    }
};

19、删除无效的括号【×】

class Solution {
public:
    vector<string> ans;

    vector<string> removeInvalidParentheses(string s) {
        int l = 0, r = 0;
        for (auto x: s)
            if (x == '(') l ++ ;
            else if (x == ')') {
                if (l == 0) r ++ ;
                else l -- ;
            }

        dfs(s, 0, "", 0, l, r);
        return ans;
    }

    void dfs(string& s, int u, string path, int cnt, int l, int r) {
        if (u == s.size()) {
            if (!cnt) ans.push_back(path);
            return;
        }

        if (s[u] != '(' && s[u] != ')') dfs(s, u + 1, path + s[u], cnt, l, r);
        else if (s[u] == '(') {
            int k = u;
            while (k < s.size() && s[k] == '(') k ++ ;
            l -= k - u;
            for (int i = k - u; i >= 0; i -- ) {
                if (l >= 0) dfs(s, k, path, cnt, l, r);
                path += '(';
                cnt ++, l ++ ;
            }
        } else if (s[u] == ')') {
            int k = u;
            while (k < s.size() && s[k] == ')') k ++ ;
            r -= k - u;
            for (int i = k - u; i >= 0; i -- ) {
                if (cnt >= 0 && r >= 0) dfs(s, k, path, cnt, l, r);
                path += ')';
                cnt --, r ++ ;
            }
        }
    }
};

20、字典序排数

class Solution {
public:
    vector<int> ans;
    vector<int> lexicalOrder(int n) {
        for(int i=1;i<=9 && i<=n;i++)
            dfs(i,n);
        return ans;
    }
    void dfs(int x,int n){
        if(x <= n){
            ans.push_back(x);
            for(int j=x*10;j<=n && j<=x*10+9;j++)
                dfs(j,n);
        }
    }
};

21、太平洋大西洋水流问题

class Solution {
public:
    int m,n;
    vector<vector<char>> st;
    int dx[4] = {-1,0,1,0}, dy[4] = {0,-1,0,1};
    void dfs(vector<vector<int>>&hs, int x,int y,int t){
        if(st[x][y] & t) return;
        st[x][y]|=t;
        for(int i=0;i<4;i++){
            int a = dx[i]+x, b = dy[i]+y;
            if(a>=0 && a<m && b>=0 && b<n && hs[a][b]>=hs[x][y])
                dfs(hs,a,b,t);
        }
    }
    vector<vector<int>> pacificAtlantic(vector<vector<int>>& hs) {
        vector<vector<int>> ans;        
        m = hs.size(), n = hs[0].size();
        if(m == 0 || n == 0) return ans;
        st = vector<vector<char>>(m,vector<char>(n));
        for(int i=0;i<n;i++) dfs(hs,0,i,1);
        for(int i=0;i<m;i++) dfs(hs,i,0,1);
        for(int i=0;i<n;i++) dfs(hs,m-1,i,2);
        for(int i=0;i<m;i++) dfs(hs,i,n-1,2);
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                if(st[i][j] == 3)
                    ans.push_back({i,j});
        return ans;
    }
};

22、扁平化多级双向链表【×】

class Solution {
public:
    Node* flatten(Node* head) {
        auto res = dfs(head);
        return res[0];
    }
    vector<Node*> dfs(Node* h){
        if(!h) return {NULL, NULL};
        auto cur=h, tail=h;
        while(cur){
            tail = cur;
            if(cur->child){
                auto t = dfs(cur->child);
                cur->child = NULL;
                if(cur->next) cur->next->prev = t[1];
                t[1]->next = cur->next;                
                cur->next = t[0];
                t[0]->prev = cur;
                cur = t[1]->next;
                tail = t[1];
            }else cur = cur->next;
        }
        return {h,tail};
    }
};

23、岛屿的周长

class Solution {
public:
    int m,n;
    int ans=0;
    int dx[4]={-1,0,1,0}, dy[4]={0,-1,0,1};
    int islandPerimeter(vector<vector<int>>& grid) {
        m = grid.size(), n = grid[0].size();
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                if(grid[i][j]) {dfs(grid,i,j); return ans;}
        return ans;
    }
    void dfs(vector<vector<int>>& grid,int x,int y){
        grid[x][y]=2;
        for(int i=0;i<4;i++){
            int a=dx[i]+x, b=dy[i]+y;
            if(a>=0 && a<m && b>=0 && b<n){
                if(grid[a][b] == 0) ans++;
                else if(grid[a][b] == 1) dfs(grid,a,b);
            }else ans++;
        }
    }
};

24、字母大小写全排列【×】

class Solution {
public:
    vector<string> ans;    
    vector<string> letterCasePermutation(string s) {
        dfs(s,0,"");
        return ans;
    }
    void dfs(string& s,int u,string path){
        if(u == s.size()) ans.push_back(path);
        else{
            dfs(s,u+1,path+s[u]);
            if(s[u]>='A'){
                s[u]^=32;
                dfs(s,u+1,path+s[u]);
            }
        }
    }
};

25、将数组拆分成斐波那契序列【×】

typedef long long ll;
class Solution {
public:
    vector<int> get(string& s,ll a,ll b){
        vector<int> res = {(int)a,(int)b};
        string t = to_string(a) + to_string(b);
        while(t.size() < s.size()){
            auto c = a+b;
            if(c > INT_MAX) return{};
            res.push_back(c);
            t+=to_string(c);
            if(t != s.substr(0,t.size()))
                return{};
            a = b; b = c;
        }
        if(t!=s) return{};
        return res;
    }
    vector<int> splitIntoFibonacci(string s) {
        // 逐一枚举前两个数
        for(int i=1;i<=10 && i<s.size();i++){
            for(int j=i+1;j<=i+10&&j<s.size();j++){
                ll a = stoll(s.substr(0,i)), b = stoll(s.substr(i,j-i));
                auto res = get(s,a,b);
                if(res.size()) return res;
            }

        }
        return {};
    }
};

[Go Back~](# LeetCode题解)

section13-2: BFS

1、单词接龙

class Solution {
public:
    int ladderLength(string begin, string end, vector<string>& wordList) {
        unordered_set<string> s;
        for(auto word:wordList) s.insert(word);
        if(!s.count(end)) return 0;
        unordered_map<string,int> dist;
        dist[begin] = 1;
        queue<string> q;
        q.push(begin);
        while(q.size()){
            string t = q.front();
            string r = t;
            q.pop();
            for(int i =0 ;i<t.size();i++){
                t = r;
                for(char j = 'a';j<='z';j++){
                    t[i] =j;
                    if(s.count(t) && !dist[t]){
                        dist[t] = dist[r] + 1;
                        if(t == end) return dist[t];
                        q.push(t);
                    }
                }
            }
        }
        return 0;
    }
};

2、单词接龙 II BFS+DFS

class Solution {
public:
    unordered_set<string> S;
    unordered_map<string, int> dist;
    queue<string> q;
    vector<vector<string>> ans;
    vector<string> path;
    string beginWord;

    vector<vector<string>> findLadders(string _beginWord, string endWord, vector<string>& wordList) {
        for (auto word: wordList) S.insert(word);
        beginWord = _beginWord;
        dist[beginWord] = 0;
        q.push(beginWord);
        while (q.size()) {
            auto t = q.front();
            q.pop();
            string r = t;
            for (int i = 0; i < t.size(); i ++ ) {
                t = r;
                for (char j = 'a'; j <= 'z'; j ++ ) {
                    t[i] = j;
                    if (S.count(t) && dist.count(t) == 0) {
                        dist[t] = dist[r] + 1;
                        q.push(t);
                    }
                }
            }
        }
        if (dist.count(endWord) == 0) return ans;
        path.push_back(endWord);
        dfs(endWord);
        return ans;
    }

    void dfs(string t) {
        if (t == beginWord) {
            reverse(path.begin(), path.end());
            ans.push_back(path);
            reverse(path.begin(), path.end());
        } else {
            string r = t;
            for (int i = 0; i < t.size(); i ++ ) {
                t = r;
                for (char j = 'a'; j <= 'z'; j ++ ) {
                    t[i] = j;
                    if (dist.count(t) && dist[t] + 1 == dist[r]) {
                        path.push_back(t);
                        dfs(t);
                        path.pop_back();
                    }
                }
            }
        }
    }
};

3、最小基因变化

class Solution {
public:
    int minMutation(string start, string end, vector<string>& bank) {
        unordered_set<string> S(bank.begin(),bank.end());
        char help[4] = {'A','C','G','T'};
        unordered_map<string,int> hash;
        queue<string> q;
        hash[start] = 1;
        q.push(start);
        while(q.size()){
            auto t = q.front(); q.pop();
            for(int i=0;i<t.size();i++){
                auto r = t;
                for(int j=0;j<4;j++){
                    r[i] = help[j];
                    if(S.count(r) && hash[r]==0){
                        hash[r] = hash[t]+1;
                        if(r == end) return hash[r]-1;
                        q.push(r);
                    }
                }
            }
        }
        return -1;
    }
};

4、员工的重要性

class Solution {
public:
    unordered_map<int,Employee*> hash;
    unordered_set<int> ids;
    int ans;
    int getImportance(vector<Employee*> employees, int id) {
        for(auto t:employees) hash[t->id] = t; 
        ans = 0;
        dfs(hash[id]);
        for(auto t:ids)
            ans+=hash[t]->importance;
        return ans;
    }
    void dfs(Employee* p){
        ids.insert(p->id);
        for(auto id:p->subordinates)
            if(ids.count(id) == 0)
                dfs(hash[id]);
    }
};

[Go Back~](# LeetCode题解)

chap-14:贪心

1、跳跃游戏

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

2、跳跃游戏 II

class Solution {
public:
    int jump(vector<int>& nums) {
        int ans=0;
        for(int i=0,tot=0,next=0;i<nums.size();i++){
            if(i <= tot){
                next = max(next,i+nums[i]);
            }else{
                tot = next;
                next = i+nums[i];
                ans++;
                if(tot>=nums.size()-1) break;
            }
        }
        return ans;
    }
};

// acwing参考
class Solution {
public:
    int jump(vector<int>& nums) {
        int ans = 0, cur = 0, dis = 0;
        while (dis < (int)nums.size() - 1) {
            int next = 0;
            while (cur <= dis) {
                next = max(next, cur + nums[cur]);
                cur++;
            }
            ans++;
            dis = next;
        }
        return ans;
    }
};

3、加油站

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int start=0, used=0, rest=0;
        for(int i=0;i<gas.size();i++){
            used+=gas[i]-cost[i];
            rest+=gas[i]-cost[i];
            if(used<0) start=i+1,used=0;
        }
        return rest>=0?start:-1;
    }
};

4、去除重复字母 栈+贪心

class Solution {
public:
    string removeDuplicateLetters(string s) {
        string ans;
        unordered_map<char,bool> f;
        unordered_map<char,int> last;
        for(int i=0;i<s.size();i++) last[s[i]]=i;
        for(int i=0;i<s.size();i++){
            if(f[s[i]]) continue;            
            while(ans.size() && ans.back() > s[i] && last[ans.back()] > i){
                f[ans.back()] = false;
                ans.pop_back();                
            }
            ans+=s[i];
            f[s[i]] = true;
        }
        return ans;
    }
};

5、按要求补齐数组【×】

class Solution {
public:
    int minPatches(vector<int>& nums, int n) {
        int ans=0,cur=0;
        long long miss=1;
        while(miss<=n){
            if(cur<nums.size() && nums[cur]<=miss){
                miss+=nums[cur];
                cur++;
            }else{
                miss<<=1;
                ans++;
            }            
        }
        return ans;
    }
};

6、摆动序列

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        // 注意第一个点的处理
        int ans=1, flag=0, t=nums[0];
        for(int i=1;i<nums.size();i++){
            if(nums[i]-t < 0 && flag >=0){
                flag = -1;
                ans++;
            }else if(nums[i]-t>0 && flag <=0){
                flag = 1;
                ans++;
            }
            t = nums[i];
        }
        return ans;
    }
};

7、移掉 K 位数字

class Solution {
public:
    string removeKdigits(string num, int k) {
        if(k == num.size()) return "0";
        string ans;
        int i=0;
        while(i<num.size()){
            while(ans.size() && ans.back() > num[i] && k>0){
                ans.pop_back();
                k--;
            }
            ans.push_back(num[i++]);            
        }
        while(k--) ans.pop_back();
        k=0; while(k<ans.size()-1 && ans[k]=='0')k++;
        return ans.substr(k);
    }
};

8、分发饼干

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        int ans=0;
        sort(g.begin(),g.end());
        sort(s.begin(),s.end());
        for(int i=0,j=0;i<g.size() && j<s.size();){
            if(g[i]<=s[j]){
                ans++; i++;j++;
            }else j++;
        }
        return ans;
    }
};

9、IPO

class Solution {
public:
    int findMaximizedCapital(int k, int w, vector<int>& p, vector<int>& c) {
        // 贪心+大根堆
        vector<pair<int,int>> vp;
        for(int i=0;i<p.size();i++){
            vp.push_back({c[i],p[i]}); // 排序顺序!
        }
        sort(vp.begin(),vp.end());
        priority_queue<int> q;
        int cur=0;
        while(k--){
            while(cur<vp.size() && vp[cur].first <= w){
                q.push(vp[cur++].second);
            }
            if(q.size()){
                w+=q.top(); q.pop();
            }
        }
        return w;
    }
};

10、种花问题

class Solution {
public:
    bool canPlaceFlowers(vector<int>& f, int n) {
        f.push_back(0);
        for(int i=0;i<f.size()-1;i++){
            if(!f[i]){
                if(!i && f[i+1]==0) n--, f[i]=1;
                if(i && f[i-1]+f[i+1] == 0) n--, f[i]=1;
            }
            if(n==0) return true;
        }
        return n<=0;
    }
};

11、Dota2 参议院

class Solution {
public:
    string predictPartyVictory(string senate) {
        // 模拟 队列
        queue<int> r,d;
        for(int i=0;i<senate.size();i++) {
            if(senate[i]=='R') r.push(i);
            if(senate[i] == 'D') d.push(i);
        }
        while(r.size() && d.size()){
            if(r.front() < d.front()){
                r.push(r.front()+senate.length());
                d.pop(); r.pop();
            }else{
                d.push(d.front()+senate.length());
                r.pop(); d.pop();
            }
        }
        return r.empty()?"Dire":"Radiant";
    }
};

12、分割数组为连续子序列

class Solution {
public:
    bool isPossible(vector<int>& nums) {
        unordered_map<int,int> cnt;
        unordered_map<int,int> chain;
        for(auto num:nums) cnt[num]++;
        for(auto num:nums){
            if(!cnt[num]) continue;
            if(chain[num-1]>0){
                cnt[num]--;
                chain[num-1]--; chain[num]++;
            }else if(cnt[num+1]>0 && cnt[num+2]>0){
                cnt[num]--;
                chain[num+2]++; 
                cnt[num+1]--; cnt[num+2]--;
            }else return false;
        }
        return true;
    }
};

// 官方思路
class Solution {
public:
    bool isPossible(vector<int>& nums) {
        // 小堆根+贪心
        unordered_map<int,priority_queue<int,vector<int>,greater<int>>> hash;
        for(auto t:nums){
            if(hash.count(t-1) && hash[t-1].size()){
                auto q = hash[t-1].top(); hash[t-1].pop();
                hash[t].push(q+1);
            }else hash[t].push(1);
        }
        for(auto &[k,v]:hash){
            if(v.size()){
                if(v.top() < 3) return false;
            }
        }
        return true;
    }
};

13、翻转矩阵后的得分

class Solution {
public:
    int matrixScore(vector<vector<int>>& grid) {
        // 模拟
        int n=grid.size(), m=grid[0].size();
        int ans=0;
        for(int i=0;i<n;i++){
            if(grid[i][0]==0){
                ans+=(1<<(m-1));
                for(int j=1;j<m;j++)
                    grid[i][j]=grid[i][j]==1?0:1;
            }else ans+=(1<<(m-1));
            for(int j=1;i&&j<m;j++){
                grid[i][j] += grid[i-1][j];
            }
        }
        for(int j=1;j<m;j++){
            int t = max(grid[n-1][j], n-grid[n-1][j]);
            ans+= t*(1<<(m-j-1));
        }
        return ans;
    }
};

14、重构字符串

class Solution {
public:
    string reorganizeString(string s) {
        int hash[26]={0};
        for(auto c:s) hash[c-'a']++;
        auto cmp = [&](const char &a, const char &b){
            return hash[a-'a'] < hash[b-'a'];
        };
        priority_queue<char,vector<char>,decltype(cmp)> q(cmp);
        for(int i=0;i<26;i++) {
            if(hash[i] > (s.size()+1)/2) return "";
            else if(hash[i]){
                q.push('a'+i);
            }
        }
        string ans; char t1,t2;
        while(q.size()>1){
            t1 = q.top();q.pop();
            t2 = q.top();q.pop();
            hash[t1-'a']--; hash[t2-'a']--;
            ans+=t1; ans+=t2;
            if(hash[t1-'a']) q.push(t1);
            if(hash[t2-'a']) q.push(t2);
        }
        if(q.size()) ans+=q.top(), q.pop();
        return ans;
    }
};

15、单调递增的数字

class Solution {
public:
    int monotoneIncreasingDigits(int n) {
        int dig[10]={0};
        int cur=0,pos=0,ans=0;
        while(n){dig[cur++] = n%10; n/=10;}
        for(int i=1;i<cur;i++){
            if(dig[i]>dig[i-1]){
                dig[i]--;
                pos=i;
            }
        }
        while(pos) {dig[pos-1]=9; pos--;}
        while(cur) {ans = ans*10 + dig[cur-1]; cur--;}
        return ans;
    }
};

16、柠檬水找零

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        int five = 0, ten = 0;
        for (int i : bills) {
            if (i == 5) five++;
            else if (i == 10) {five--; ten++;}
            else if (ten > 0) {ten--; five--;} 
            else five -= 3;
            if (five < 0) return false;
        }
        return true;
    }
};

17、可以到达的最远建筑

class Solution {
public:
    int furthestBuilding(vector<int>& hs, int bs, int ls) {
        priority_queue<int> q;
        int t=0;
        for(int i=hs.size()-1;i>0;i--) hs[i]-=hs[i-1];
        int i=1;
        for(;i<hs.size();i++){
            if(hs[i]<=0) continue;
            if(!ls && t+hs[i]>bs) return i-1;
            if(ls) {
                if(t+hs[i]<=bs) {t+=hs[i]; q.push(hs[i]);}
                else{
                    if(q.size() && q.top()<hs[i]) ls--;
                    else if(q.empty()) ls--;
                    else {t-=q.top(); t+=hs[i]; q.pop(); ls--; q.push(hs[i]);}
                }
            }else t+=hs[i];
        }
        return i-1;
    }
};

class Solution {
public:
    int furthestBuilding(vector<int>& heights, int bricks, int ladders) {
        priority_queue<int, vector<int>, greater<int>> q;
        for (int i = 1; i < heights.size(); i++) {
            if (heights[i] <= heights[i - 1]) continue;
            int d = heights[i] - heights[i - 1];
            if (ladders > 0) {
                ladders--; q.push(d); // 有梯子时先考虑梯子
            } else {
                if (!q.empty() && d > q.top()) {
                    if (bricks < q.top())  return i - 1;
                    bricks -= q.top();
                    q.pop();
                    q.push(d);
                } else {
                    if (bricks < d)  return i - 1;
                    bricks -= d;
                }
            }
        }
        return n - 1;
    }
};

18、销售价值减少的颜色球

#define LL long long

class Solution {
public:
    int maxProfit(vector<int>& inventory, int orders) {
        const int mod = 1000000007;
        const int n = inventory.size() + 1;

        inventory.push_back(0);
        sort(inventory.begin(), inventory.end());

        LL ans = 0;
        for (int i = n - 1; i >= 1; i--) {
            if (orders >= (LL)(inventory[i] - inventory[i - 1]) * (n - i)) {
                orders -= (inventory[i] - inventory[i - 1]) * (n - i);

                int s = inventory[i - 1] + 1, t = inventory[i], num = t - s + 1;
                ans = (ans + (LL)(s + t) * num / 2 % mod * (n - i)) % mod;
            } else {
                int num = orders / (n - i);
                int t = inventory[i], s = t - num + 1;
                ans = (ans + (LL)(s + t) * num / 2 % mod * (n - i)) % mod;

                int r = orders % (n - i);
                ans = (ans + (LL)(r) * (t - num)) % mod;
                break;
            }
        }
        return ans;
    }
};

19、找出最具竞争力的子序列

class Solution {
public:
    vector<int> mostCompetitive(vector<int>& nums, int k) {
        const int n = nums.size();
        deque<int> q;
        vector<int> ans;

        for (int i = 0; i < n; i++) {
            while (!q.empty() && nums[i] < nums[q.back()])
                q.pop_back();
            q.push_back(i);
            if (i >= n - k) {
                ans.push_back(nums[q.front()]);
                q.pop_front();
            }
        }
        return ans;
    }
};

// 使用vector模拟队列
class Solution {
public:
    vector<int> mostCompetitive(vector<int>& nums, int k) {
        const int n = nums.size();
        vector<int> ans;

        for (int i = 0; i < n; i++) {
            while (!ans.empty() && ans.size() + n - i > k && nums[i] < ans.back())
                ans.pop_back();

            if (ans.size() < k)
                ans.push_back(nums[i]);
        }
        return ans;
    }
};

[Go Back~](# LeetCode题解)

section14-1: 区间贪心

1、无重叠区间【最大不相交区间数量】

class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        int ans=0;
        auto cmp=[&](const vector<int>&a, const vector<int>&b){
            if(a[1]==b[1]) return (a[1]-a[0])<(b[1]-b[0]);
            else return a[1]<b[1];
        };
        sort(intervals.begin(),intervals.end(),cmp);
        int last=INT_MIN;
        for(auto &t:intervals){
            if(t[0]>=last) last = t[1];
            else ans++;
        }
        return ans;
    }
};

2、用最少数量的箭引爆气球【区间选点】

class Solution {
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        auto cmp = [&](const vector<int>&a, const vector<int>&b){
            return a[1]<b[1];
        };
        sort(points.begin(),points.end(),cmp);
        int ans=0, s=points[0][0], e=points[0][1];
        for(int i=1;i<points.size();i++){
            if(points[i][0]<=e && points[i][1] >= s){
                s = max(s,points[i][0]);
                e = min(e,points[i][1]);
            }else{
                ans++;
                s = points[i][0];
                e = points[i][1];
            }
        }
        return ans+1;
    }
};

3、视频拼接【区间覆盖】

class Solution {
public:
    int videoStitching(vector<vector<int>>& clips, int time) {
        auto cmp = [&](const vector<int>&a, const vector<int>&b){
            return a[0]<b[0];
        };
        sort(clips.begin(),clips.end(),cmp);
        int ans=0, s=0;
        for(int i=0;i<clips.size();){
            if(clips[i][0]>s) return -1;
            int e = 0;
            while(i<clips.size() && clips[i][0]<=s)
                e=max(clips[i][1],e), i++;
            ans++; s=e;
            if(e>=time) return ans;
        }
        return -1;
    }
};

[Go Back~](# LeetCode题解)

posted @ 2022-02-14 01:24  SrtFrmGNU  阅读(28)  评论(0编辑  收藏  举报