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题解)
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。