文章目录
- 重做题目 300,301,306,307,309,310,312,313,315,316,318,321,322,324,329,330,331,332,334,337,338,341,342,343,347,352,354,355,365,368,369,370,371,373,375,376,377,378,379,380,382,384,386,389,395,397,398,399
- 300. 最长上升子序列
- 301. 删除无效的括号
- 303. 区域和检索 - 数组不可变
- 307. 区域和检索 - 数组可修改
- 309. 最佳买卖股票时机含冷冻期
- 310. 最小高度树
- 312. 戳气球
- 313. 超级丑数
- 315. 计算右侧小于当前元素的个数
- 316. 去除重复字母
- 318. 最大单词长度乘积
- 321. 拼接最大数
- 322. 零钱兑换
- 324. 摆动排序 II
- 328. 奇偶链表
- 329. 矩阵中的最长递增路径
- 330. 按要求补齐数组
- 331. 验证二叉树的前序序列化
- 334. 递增的三元子序列
- 337. 打家劫舍 III
- 338. 比特位计数
- 341. 扁平化嵌套列表迭代器
- 342. 4的幂
- 343. 整数拆分
- 344. 反转字符串
- 347. 前 K 个高频元素(sort排序)
- 349. 两个数组的交集
- 350. 两个数组的交集 II
- 352. 将数据流变为多个不相交区间
- 354. 俄罗斯套娃信封问题(最大递增子序列)
- 355. 设计推特
- 357. 计算各个位数不同的数字个数
- 365. 水壶问题
- 367. 有效的完全平方数
- 368. 最大整除子集(*******路径记录*********)
- 369. 给单链表加一
- 371. 两整数之和(位运算)
- 370. 区间加法
- 371. 两整数之和
- 373. 查找和最小的K对数字(堆排序(优先队列)****************)
- 374. 猜数字大小(二分法)
- 376. 摆动序列
- 377. 组合总和 Ⅳ(dfs,dp)
- 378. 有序矩阵中第K小的元素
- 379. 电话目录管理系统
- 380. 常数时间插入、删除和获取随机元素(next函数)
- 382. 链表随机节点
- 383. 赎金信
- 386. 字典序排数
- 389. 找不同
- 392. 判断子序列
- 394. 字符串解码(好)
- 395. 至少有K个重复字符的最长子串
- 397. 整数替换
- 398. 随机数索引
- 399. 除法求值(并查集)
重做题目 300,301,306,307,309,310,312,313,315,316,318,321,322,324,329,330,331,332,334,337,338,341,342,343,347,352,354,355,365,368,369,370,371,373,375,376,377,378,379,380,382,384,386,389,395,397,398,399
300. 最长上升子序列
注意是子序列而不是子串,所以这里递归的办法要变一下
注意是求dp里面的最大值,而不是某位的值,因为不一定最大
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int len = nums.size();
if(len==0)return 0;
vector<int> dp(len,0);
dp[0]=1;
int res=0;
for(int i = 0 ; i< len ;i++)
{
int m = 1;
for(int j = 0 ; j< i ; j++)
{
if(nums[j]<nums[i]){m = max(m,dp[j]+1);}
}
dp[i] = m;
if(m>res) res = m;
}
return res;
}
};
301. 删除无效的括号
class Solution {
public:
bool isok(string s)
{
stack<char> st;
//if(s.size()%2!=0)return false;
int i=0;
while(i<s.size())
{
if(s[i]=='(')st.push(s[i]);
else if(s[i]==')')
{
if(st.empty())return false;
auto temp =st.top();
if(temp=='(')
{
st.pop();
}
else
{
st.push(s[i]);
}
}
i++;
}
return st.empty();
}
vector<string> res;
string path = "";
int m = 0;
void dfs(string s,int p)
{
if(isok(path))
{
if(res.empty())res.push_back(path);
else
{
if (path.size() >= m)
{
while (!res.empty() && res.back().size() < path.size() && res.back() != path)res.pop_back();
res.push_back(path);
m = max(m,(int)path.size());
}
}
}
if(p==s.size())return;
path += s[p];
dfs(s,p+1);
path.pop_back();
dfs(s,p+1);
}
vector<string> removeInvalidParentheses(string s) {
dfs(s,0);
set<string> st(res.begin(),res.end());
vector<string> r(st.begin(),st.end());
return r;
}
};
303. 区域和检索 - 数组不可变
class NumArray {
private:
vector<int> data;
public:
NumArray(vector<int>& nums) {
data = nums;
}
int sumRange(int i, int j) {
int sum=0;
//NumArray();
for(int c = i ;c<=j ;c++)
{
sum +=data[c];
}
return sum;
}
};
/**
* Your NumArray object will be instantiated and called as such:
* NumArray* obj = new NumArray(nums);
* int param_1 = obj->sumRange(i,j);
*/
307. 区域和检索 - 数组可修改
树状数组解法
class NumArray {
public:
vector<int> tree; int n;//数组的长度
vector<int> old;
int lowbit(int x)
{
return x & (-x);
}
void update(int i, int val) {
i++;
int t = val - old[i];
old[i] = val;
while (i <= n)
{
tree[i] += t;
i += lowbit(i);
}
}
NumArray(vector<int> nums) {
old = vector<int>(100000, 0);
tree = vector<int>(100000, 0);
n = nums.size();
for (int i = 0; i < nums.size(); i++)
{
update(i, nums[i]);
}
}
int sumRange(int i, int j) {
j++;
int r1 = 0, r2 = 0;
while (i > 0)
{
r1 += tree[i];
i -= lowbit(i);
}
while (j > 0)
{
r2 += tree[j];
j -= lowbit(j);
}
return r2 - r1;
}
};
/**
* Your NumArray object will be instantiated and called as such:
* NumArray* obj = new NumArray(nums);
* obj->update(i,val);
* int param_2 = obj->sumRange(i,j);
*/
线段树解法
class NumArray {
public:
vector<int> tree;
vector<int> m_nums;
void buidtree(int node, int start ,int end)
{
if(start==end){tree[node]=m_nums[start];return;}
int mid = start + (end -start)/2;
int left_node = 2*node + 1;
int right_node = 2*node +2;
buidtree(left_node,start,mid);
buidtree(right_node,mid+1,end);
tree[node] = tree[left_node] + tree[right_node];
}
void update_tree(int node, int start,int end,int i,int val)
{
if (start == end) { tree[node] = val; m_nums[start] = val; return; }
int mid = start + (end -start)/2;
int left_node = 2*node + 1;
int right_node = 2*node +2;
if(i>=start && i<=mid)update_tree(left_node,start,mid,i,val);
else update_tree(right_node,mid+1,end,i,val);
tree[node] = tree[left_node] + tree[right_node];
}
int query_tree(int node,int start,int end,int i,int j)
{
if(j<start || i>end)return 0;
if(start==end)return tree[node];
int mid = start + (end -start)/2;
int left_node = 2*node + 1;
int right_node = 2*node +2;
int left_sum = query_tree(left_node,start,mid,i,j);
int right_sum = query_tree(right_node,mid+1,end,i,j);
return left_sum + right_sum;
}
NumArray(vector<int>& nums) {
if(nums.empty())return;
m_nums = nums;
tree = vector<int>(m_nums.size()*4,0);
buidtree(0,0,m_nums.size()-1);
}
void update(int i, int val) {
update_tree(0,0,m_nums.size()-1,i,val);
}
int sumRange(int i, int j) {
return query_tree(0,0,m_nums.size()-1,i,j);
}
};
/**
* Your NumArray object will be instantiated and called as such:
* NumArray* obj = new NumArray(nums);
* obj->update(i,val);
* int param_2 = obj->sumRange(i,j);
*/
309. 最佳买卖股票时机含冷冻期
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.empty())return 0;
if(prices.size()==1)return 0;
if(prices.size()==2)return max(0,prices[1]-prices[0]);
vector<int> dp(prices.size(),0);
dp[0]=0;
dp[1]=max(0,prices[1]-prices[0]);
dp[2]=max(0,max(prices[2]-prices[0],max(prices[2]-prices[1],prices[1]-prices[0])));
for(int i = 3;i<prices.size();i++)
{
int m1 = 0;
for(int j = 0;j<=i-3;j++)
{
int m2 = 0;
for(int k = j+2;k<=i-1;k++)
{
m2 = max(m2,prices[i]-prices[k]);
}
m1 = max(m1,dp[j]+m2);
}
m1 = max(m1,max(prices[i]-prices[0],max(prices[i]-prices[1],prices[i]-prices[2])));
dp[i] = m1;
}
return *max_element(dp.begin(),dp.end());
}
};
310. 最小高度树
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
unordered_map<int,vector<int>> mp;
vector<int> level(n,0);
for(auto&e:edges)
{
mp[e[0]].push_back(e[1]);
mp[e[1]].push_back(e[0]);
level[e[0]]++;
level[e[1]]++;
}
queue<int> qt;
for(int i = 0 ;i<n;i++)
{
if(level[i]==1)qt.push(i);
}
while(n>2)
{
int len = qt.size();
n -= len;
for(int i = 0 ; i<len;i++)
{
auto temp = qt.front();qt.pop();
for(auto&t:mp[temp])
{
level[temp]--;
level[t]--;
if(level[t]==1)qt.push(level[t]);
}
}
}
vector<int> res;
while(!qt.empty())
{
res.push_back(qt.front());qt.pop();
}
return res;
}
};
312. 戳气球
class Solution {
public:
int maxCoins(vector<int>& nums) {
// "我们令dp[start][end]表示从start到end之间的气球戳破之后能得到的最大值"
// 这里的start和end是不会被戳爆的,也就是一个start到end的开区间
// transition eqn :
// dp[start][end] = dp[start][i] + dp[i][end] + nums[start] * nums[i] * nums[end]
const int numSize(nums.size());
// 前后补上两个“哨兵”,这样原数组的两边就不需要单独处理
// 是链表中常用的技巧
nums.insert(nums.begin(), 1);
nums.insert(nums.end(), 1);
// 因为补上了两个,所以长度变成了numSize +
int **dp = new int* [numSize + 2];
for(int i = 0; i < numSize + 2; ++i)
dp[i] = new int[numSize + 2];
// 这里倒着遍历,因为从transition eqn能看出来,我们每次需要的是后面的值
// 也就是dp[start][i]和dp[i][end],而不需要start之前的值
for(int start = numSize + 1; start >= 0; --start) {
for(int end = start; end < numSize + 2; ++end) {
// 如果区间气球总数不够三个,那就别戳了
if(end - start < 2) { dp[start][end] = 0; continue; }
for(int i = start + 1; i < end; ++i)
dp[start][end] =
max(dp[start][end],
dp[start][i] + dp[i][end] + nums[start] * nums[i] * nums[end]);
}
}
// return的时候就取最长,这里从0到最后正好不包含两个“哨兵”
return dp[0][numSize + 1];
}
};
313. 超级丑数
class Solution {
public:
int nthSuperUglyNumber(int n, vector<int>& primes) {
vector<int> dp = {1};
vector<int> pos(primes.size(),0);
while(n>1)
{
int temp = INT_MAX;
for(int i = 0 ; i<primes.size();i++)
{
temp = min(temp,dp[pos[i]]*primes[i]);
}
for(int i = 0;i<primes.size();i++)
{
if(temp == dp[pos[i]]*primes[i])pos[i]++;
}
dp.push_back(temp);
n--;
}
return dp.back();
}
};
315. 计算右侧小于当前元素的个数
//
// main.cpp
// 315_countSmaller
//
// Created by bella on 2020/7/11.
// Copyright © 2020 bella. All rights reserved.
//
#include <iostream>
#include <vector>
#include <map>
using namespace std;
using namespace std;
class Solution {
public:
int lowbit(int x){
return x & (-x);
}
void update(int i, vector<int>&C){
while (i < C.size()) {
C[i]++;
i += lowbit(i);
}
}
void query(int i, int j, vector<int>&C, vector<int>&counts){
while (i >= 1) {
counts[j] += C[i];
i -= lowbit(i);
}
}
vector<int> countSmaller(vector<int>& nums) {
vector<int>counts(nums.size(), 0);
if (nums.size() < 1) {
return counts;
}
vector<int>N(nums);
// Sort and unique
sort(N.begin(), N.end());
int slow = 1;
int fast = 1;
while(fast< N.size()) {
if (N[fast] != N[slow - 1]) {
N[slow] = N[fast];
slow++;
fast++;
}else{
fast++;
}
}
N.resize(slow);
// key: number, value: i
map<int, int>m;
for (int j = 1; j < 1 + N.size(); ++j) {
m[N[j - 1]] = j;
}
// traverse
vector<int>C(N.size() + 1, 0); // C[i] is necessary, but A[i] not
int i;
for (int j = nums.size() - 1; j >= 0; --j) {
i = m[nums[j]];
update(i, C);
if (i != 1) {
query(i - 1, j, C, counts);
}else{
counts[j] = 0;
}
}
return counts;
}
};
int main(int argc, const char * argv[]) {
Solution s;
const int LEN = 8;
int arr[LEN] = {7, 5, 6, 5, 2, 6, 5, 1};
vector<int>vec(arr, arr + LEN);
s.countSmaller(vec);
return 0;
}
作者:yangbingjie
链接:https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/solution/shu-zhuang-shu-zu-de-xiang-xi-fen-xi-by-yangbingji/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
vector<int> countSmaller(vector<int>& nums) {
int n = nums.size();
if(n == 0)
return {};
// ordered_arr存储排序后的有序数组
vector<int> ordered_arr, res;
for(int i = n - 1; i >= 0; i--)
{
// 通过lower_bound()函数得到在ordered_arr中的index
auto index = lower_bound(ordered_arr.begin(), ordered_arr.end(), nums[i]);
// count记录在nums[i]右侧且比nums[i]小的元素个数
int count = index - ordered_arr.begin();
// 倒序逐个插入元素
ordered_arr.insert(index,nums[i]);
// 插入count值
res.push_back(count);
}
// 由于数组是从后向前遍历的,所以还需要反转数组
reverse(res.begin(),res.end());
return res;
}
};
作者:Sunny_SMILE
链接:https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/solution/315-ji-suan-you-ce-xiao-yu-dang-qian-yuan-su-de-9/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
316. 去除重复字母
class Solution {
public:
string removeDuplicateLetters(string s) {
stack<char> st;
unordered_set<char> stt;
for(int i = 0 ;i<s.size();i++)
{
if(stt.find(s[i])!=stt.end())continue;
if(st.empty())st.push(s[i]);
else
{
auto temp = st.top();
if(temp<s[i])st.push(s[i]);
else
{
while(!st.empty() && st.top()>=s[i] && find(s.begin()+i,s.end(),st.top())!=s.end() ){stt.erase(st.top());st.pop();}
st.push(s[i]);
}
}
stt.insert(s[i]);
}
string res = "";
while(!st.empty())
{
res = st.top() + res;
st.pop();
}
return res;
}
};
318. 最大单词长度乘积
&的优先级
比较特殊比==等还低,所以以后使用&一定要加小括号
左移<<
1<<x代表移x位,得到的就是x位为1的树,再通过与操作合并到temp上
class Solution {
public:
int maxProduct(vector<string> words) {
int len = words.size();
vector<int> vt(len);
for(int i = 0;i<len;i++)
{
int temp =0;
for(auto&w:words[i])
{
temp = temp | 1<<(w-'a');
}
vt[i]=temp;
}
int res = 0;
for(int i = 0;i<len;i++)
{
for(int j = i+1;j<len;j++)
{
if((vt[i]&vt[j])==0)
{
res = max(res,(int)words[i].size()*(int)words[j].size());
}
}
}
return res;
}
};
321. 拼接最大数
dfs超时
class Solution {
public:
vector<int> res;
int m = 0;
vector<int> path;
void dfs(vector<int>& nums1, vector<int>& nums2,int sum,int k,int p,int q)
{
if(path.size()==k)
{
if(sum>m)
{
res = path;
m = sum;
}
return;
}
if(path.size()>k)return;
if(p>=nums1.size() && q>=nums2.size())return;
if(p<nums1.size())
{
dfs(nums1,nums2,sum,k,p+1,q);
path.push_back(nums1[p]);
int temp = sum;
sum = sum*10 + nums1[p];
dfs(nums1,nums2,sum,k,p+1,q);
sum = temp;
path.pop_back();
}
if(q<nums2.size())
{
dfs(nums1,nums2,sum,k,p,q+1);
path.push_back(nums2[q]);
int temp = sum;
sum =sum*10+ nums2[q];
dfs(nums1,nums2,sum,k,p,q+1);
sum = temp;
path.pop_back();
}
if(p<nums1.size() && q<nums2.size())
{
dfs(nums1,nums2,sum,k,p+1,q+1);
int temp = sum;
path.push_back(nums1[p]);
path.push_back(nums2[q]);
sum = sum*10+ nums1[p];
sum = sum*10 + nums2[q];
dfs(nums1,nums2,sum,k,p+1,q+1);
sum = temp;
path.pop_back();
path.pop_back();
path.push_back(nums2[q]);
path.push_back(nums1[p]);
sum = sum*10+ nums2[q];
sum = sum*10 + nums1[p];
dfs(nums1,nums2,sum,k,p+1,q+1);
sum = temp;
path.pop_back();
path.pop_back();
}
}
vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
dfs(nums1,nums2,0,k,0,0);
return res;
}
};
322. 零钱兑换
int coinChange(vector<int>& coins, int amount) {
// 数组大小为 amount + 1,初始值也为 amount + 1
vector<int> dp(amount + 1, amount + 1);
// base case
dp[0] = 0;
for (int i = 0; i < dp.size(); i++) {
// 内层 for 在求所有子问题 + 1 的最小值
for (int coin : coins) {
// 子问题无解,跳过
if (i - coin < 0) continue;
dp[i] = min(dp[i], 1 + dp[i - coin]);
}
}
return (dp[amount] == amount + 1) ? -1 : dp[amount];
}
作者:labuladong
链接:https://leetcode-cn.com/problems/coin-change/solution/dong-tai-gui-hua-tao-lu-xiang-jie-by-wei-lai-bu-ke/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
324. 摆动排序 II
三色排序,后面处理没看懂
class Solution {
public:
void wiggleSort(vector<int>& nums) {
// 找到中位数
auto nth=nums.begin()+nums.size()/2;
nth_element(nums.begin(), nth, nums.end());
int mid=*nth;
// 三路切分
int i=0, j=0, k=nums.size()-1;
while(j<k){
if(nums[j]>mid) swap(nums[j], nums[k--]);
else if(nums[j]<mid) swap(nums[i++], nums[j++]);
else ++j;
}
// 穿插排序
if(nums.size()&0x01) ++nth;
vector<int> v1(nums.begin(), nth);
vector<int> v2(nth, nums.end());
for(int i=0; i<v1.size(); ++i) nums[i*2]=v1[v1.size()-1-i];
for(int i=0; i<v2.size(); ++i) nums[i*2+1]=v2[v2.size()-1-i];
}
};
作者:minux_sufe
链接:https://leetcode-cn.com/problems/wiggle-sort-ii/solution/mix-xue-xi-da-lao-de-si-lu-by-minux_sufe/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
328. 奇偶链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* oddEvenList(ListNode* head) {
if(!head || !head->next)return head;
auto temp = head;
auto o = new ListNode(0);
auto head1 = o;
auto e = new ListNode(0);
auto head2 = e;
while(temp)
{
o->next = temp;
o = temp;
temp = temp->next;
if(temp)
{
e->next = temp;
e = temp;
temp = temp->next;
}
}
e->next = NULL;
o->next = head2->next;
return head1->next;
}
};
329. 矩阵中的最长递增路径
class Solution {
public:
int l = 0;
set<pair<int,int>> st;
void dfs(vector<vector<int>>& matrix,int m,int n,int i,int j)
{
l = max(l,(int)st.size());
if(i+1<m && matrix[i+1][j]>matrix[i][j] && st.find(make_pair(i+1,j))==st.end())
{
st.insert(make_pair(i+1,j));
dfs(matrix, m,n,i+1,j);
st.erase(make_pair(i+1,j));
}
if(i-1>=0 && matrix[i-1][j]>matrix[i][j] && st.find(make_pair(i-1,j))==st.end())
{
st.insert(make_pair(i-1,j));
dfs(matrix, m,n,i-1,j);
st.erase(make_pair(i-1,j));
}
if(j+1<n && matrix[i][j+1]>matrix[i][j] && st.find(make_pair(i,j+1))==st.end())
{
st.insert(make_pair(i,j+1));
dfs(matrix, m,n,i,j+1);
st.erase(make_pair(i,j+1));
}
if(j-1>=0 && matrix[i][j-1]>matrix[i][j] && st.find(make_pair(i,j-1))==st.end())
{
st.insert(make_pair(i,j-1));
dfs(matrix, m,n,i,j-1);
st.erase(make_pair(i,j-1));
}
}
int longestIncreasingPath(vector<vector<int>> matrix) {
if(matrix.empty())return 0;
int m = matrix.size();
int n = matrix[0].size();
int count =0;
vector<int> result;
for(int i = 0;i<m;i++)
{
for(int j = 0;j<n;j++)
{
st.clear();
l=0;
st.insert(make_pair(i,j));
dfs(matrix,m,n,i,j);
count = max(l,count);
}
}
return count;
}
};
330. 按要求补齐数组
class Solution {
public:
int minPatches(vector<int>& nums, int n) {
int number = 0;
long int i = 1;
int j = 0;
while (i <= n)
{
if (j < nums.size() && i >= nums[j])
{
i = i + nums[j++];
}
else
{
number++;
i = i * 2;
}
}
return number;
}
};
331. 验证二叉树的前序序列化
槽的思想
class Solution {
public:
bool isValidSerialization(string preorder) {
if(preorder.empty())return true;
int slot = 1;
int i = 0;
while(i<preorder.size())
{
int j = i;
while(i<preorder.size() && preorder[i]!=',')i++;
auto temp = preorder.substr(j,i-j);
i++;
if(temp=="#")
{
slot--;
if(slot==0 && i<preorder.size())return false;
if(slot<0)return false;
}
else
{
slot++;
}
}
return slot==0;
}
};
class Solution {
public:
vector<string> findItinerary(vector<vector<string>>& tickets) {
// 两个机场间可能有多张机票,所以value用int来计数
// map保证value有序,可以保证第一个搜索结果即为最终结果
map<string, map<string, int>> m, vis;
for(auto t: tickets) m[t[0]][t[1]]++;
vector<string> res, cur;
// 添加起始点
cur.push_back("JFK");
dfs(m, vis, cur, tickets.size()+1, res);
return res;
}
void dfs(map<string, map<string, int>>& m, map<string, map<string, int>>& vis, vector<string>& cur, int n, vector<string>& res) {
// 如果已经找到一个结果,直接返回
if(res.size()==n) return;
if(cur.size()==n) {
res = cur;
return;
}
// 没有以当前机场为起点的机票,中止搜索
if(m.find(cur.back())==m.end()) return;
// 遍历
for(auto it: m[cur.back()]) {
string stop = it.first;
// 根据机票数量判断是否可以继续搜索
if(vis[cur.back()][stop]==it.second) continue;
vis[cur.back()][stop]++;
cur.push_back(stop);
dfs(m, vis, cur, n, res);
cur.pop_back();
vis[cur.back()][stop]--;
// 如果已经找到一个结果,直接返回
if(res.size()==n) return;
}
}
};
作者:trsteel
链接:https://leetcode-cn.com/problems/reconstruct-itinerary/solution/shen-du-you-xian-sou-suo-by-trsteel/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
vector<string> res;
vector<string> path;
map<pair<string, string>, int> st;
bool b = false;
void dfs(unordered_map<string, set<string>>& mp, int n)
{
if (b)return;
if (path.size() == n + 1)
{
res = path;
b = true;
return;
}
auto temp = path.back();
for (auto&m : mp[temp])
{
if (st[make_pair(temp, m)] > 0)
{
st[make_pair(temp, m)]--;
path.push_back(m);
dfs(mp, n);
st[make_pair(temp, m)]++;
path.pop_back();
}
}
}
vector<string> findItinerary(vector<vector<string>> tickets) {
unordered_map< string, set<string> > mp;
for (auto&t : tickets)
{
mp[t[0]].insert(t[1]);
st[make_pair(t[0], t[1])]++;
}
path.push_back("JFK");
dfs(mp, tickets.size());
return res;
}
};
334. 递增的三元子序列
class Solution {
public:
bool increasingTriplet(vector<int>& nums) {
if(nums.size()<=2)return false;
int small = INT_MAX;
int mid = INT_MAX;
for(int i =0;i<nums.size();i++)
{
if(nums[i]<=small)
{
small = nums[i];
}
else if(nums[i]<=mid)
{
mid = nums[i];
}
else if(nums[i]>mid && mid>small)
{
return true;
}
}
return false;
}
};
337. 打家劫舍 III
class Solution {
public int rob(TreeNode root) {
//计算当前节点偷与不偷所能获得收益,结果存在数组result中
int[] result = countSum(root);
//根据题意可知需取其中最大的
return Math.max(result[0],result[1]);
}
public int[] countSum(TreeNode root){
int[] result = new int[2];
//如果当前节点为空节点,则其结果为0
if(root == null){
return result;
}
//计算当前节点左儿子偷与不偷所能获得的收益
int[] left = countSum(root.left);
//计算当前节点右儿子偷与不偷所能获得的收益
int[] right = countSum(root.right);
//不偷当前节点所能获得的最大收益 = 左儿子所能获得的最大收益 + 右儿子所能获得的最大收益
result[0] = Math.max(left[0],left[1])+Math.max(right[0],right[1]);
//偷当前节点所能获得的最大收益= 偷当前节点的钱 + 不偷左儿子所获得的钱 +不偷右儿子所获得的钱
result[1] = root.val+left[0]+right[0];
return result;
}
}
作者:ming-zhi-shan-you--m9RfkvKDad
链接:https://leetcode-cn.com/problems/house-robber-iii/solution/337-da-jia-jie-she-iii-by-ming-zhi-shan-you-m9rf-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
pair<int,int> dfs(TreeNode* root)
{
if(!root)return make_pair(0,0);
auto left = dfs(root->left);
auto right = dfs(root->right);
pair<int,int> temp;
temp.first = max(left.first,left.second) + max(right.first, right.second);
temp.second = root->val + left.first + right.first;
return temp;
}
int rob(TreeNode* root) {
auto res = dfs(root);
return max(res.first,res.second);
}
};
338. 比特位计数
class Solution {
public:
vector<int> countBits(int num) {
vector<int> res(num+1,0);
for(int i = 1;i<=num;i++)
{
res[i]=res[i&(i-1)]+1;
}
return res;
}
};
341. 扁平化嵌套列表迭代器
class NestedIterator {
private:
stack<NestedInteger> st;
public:
NestedIterator(vector<NestedInteger> &nestedList) {
for (auto iter = nestedList.rbegin(); iter != nestedList.rend(); iter++) {
st.push(*iter);
}
}
int next() {
auto t = st.top();
st.pop();
return t.getInteger();
}
bool hasNext() {
while (!st.empty()) {
auto cur = st.top();
if (cur.isInteger()) return true;
st.pop();
auto curList = cur.getList();
for (auto iter = curList.rbegin(); iter != curList.rend(); iter++) {
st.push(*iter);
}
}
return false;
}
};
作者:fxxuuu
链接:https://leetcode-cn.com/problems/flatten-nested-list-iterator/solution/c-zong-he-ge-lu-da-lao-de-da-an-by-fxxuuu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
342. 4的幂
class Solution {
public:
bool isPowerOfFour(int num) {
if(num<0) return false;
return (num&(num-1))==0&&(num&0b01010101010101010101010101010101)!=0;
}
};
作者:li-xue-bing
链接:https://leetcode-cn.com/problems/power-of-four/solution/wei-yun-suan-by-li-xue-bing/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
343. 整数拆分
暴力法
//C
class Solution {
public:
int integerBreak(int n)
{
vector<int> dp(n 1, 0);
dp[1] = 1;
for (int i = 2; i <= n; i )
{
for (int j = 1; j < i; j )
{
dp[i] = max(dp[i], max(dp[j], j) * (i - j));
}
}
return(dp[n]);
}
};
作者:ivan1
链接:https://leetcode-cn.com/problems/integer-break/solution/tan-xin-suan-fa-dong-tai-gui-hua-zong-you-yi-ge-sh/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
// ac地址:https://leetcode-cn.com/problems/integer-break/
// 原文地址:https://xxoo521.com/2020-02-15-integer-break/
/**
* @param {number} n
* @return {number}
*/
var integerBreak = function(n) {
const dp = new Array(n + 1).fill(1);
for (let i = 3; i <= n; ++i) {
for (let j = 1; j < i; ++j) {
dp[i] = Math.max(dp[i], j * (i - j), j * dp[i - j]);
}
}
return dp[n];
};
作者:xin-tan
链接:https://leetcode-cn.com/problems/integer-break/solution/shuang-jie-fa-dong-tai-gui-hua-tan-xin-fa-fu-zhao-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
// ac地址:https://leetcode-cn.com/problems/integer-break/
// 原文地址:https://xxoo521.com/2020-02-15-integer-break/
/**
* @param {number} n
* @return {number}
*/
var integerBreak = function(n) {
if (n === 2) return 1;
if (n === 3) return 2;
// a的含义:n能拆成的3的个数
const a = Math.floor(n / 3);
const b = n % 3;
// n是3的倍数
if (b === 0) return Math.pow(3, a);
// n是 3k + 1,例如7。拆成3、3、1。由于有1对结果无法有贡献,所以最后的3、1换成4
if (b === 1) return Math.pow(3, a - 1) * 4;
return Math.pow(3, a) * 2;
};
作者:xin-tan
链接:https://leetcode-cn.com/problems/integer-break/solution/shuang-jie-fa-dong-tai-gui-hua-tan-xin-fa-fu-zhao-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
344. 反转字符串
class Solution {
public:
void reverseString(vector<char>& s) {
//reverse(s.begin(),s.end());
int i = 0;
int j = s.size()-1;
while(i<j)
{
swap(s[i++],s[j--]);
}
return ;
}
};
由于是有序矩阵,那么左上角的数字一定是最小的,而右下角的数字一定是最大的,所以这个是我们搜索的范围,然后我们算出中间数字mid,由于矩阵中不同行之间的元素并不是严格有序的,所以我们要在每一行都查找一下mid,我们使用upper_bound,这个函数是查找第一个大于目标数的元素,如果目标数在比该行的尾元素大,则upper_bound返回该行元素的个数,如果目标数比该行首元素小,则upper_bound返回0, 我们遍历完所有的行可以找出中间数是第几小的数,然后k比较,进行二分查找,left和right最终会相等,并且会变成数组中第k小的数字。(方便理解,我们没有直接使用upper_bound函数,但道理一样)。
————————————————
版权声明:本文为CSDN博主「pushup8」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/pushup8/article/details/85200248
class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
int row = matrix.size(), col = matrix[0].size();
int low = matrix[0][0], high = matrix[row - 1][col - 1];
while(low < high){
int mid = (low + high) / 2, j = col - 1, cnt = 0;
for(int i = 0; i < row; i++){
while(j >=0 && matrix[i][j] > mid)j--;
cnt +=(j + 1);
}
if(cnt < k) low = mid + 1;
else high = mid;
}
return low;
}
};
这里面有一个很关键的问题是,可能直接等于k的那个数不在矩阵中下面是解释看到通过二分法在矩阵元素的最大值和最小值之间查找恰好使小于等于该值的矩阵元素为k个的值,这个值即为所求结果的方法,觉得有可能查到的值不在矩阵元素中,但后来发现如果并不是一查到符合条件的值(小于等于该值的矩阵元素有k个)就返回,而是继续二分,直到上下界相等,然后返回此时的下界/上界,由于矩阵中均为整数,是可以保证查到的值在矩阵内且小于等于该值的矩阵元素恰好有k个的。
作者:shimura233
链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/solution/guan-yu-wei-shi-yao-er-fen-cha-zhao-zui-hou-fan-hu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
347. 前 K 个高频元素(sort排序)
关于对哈希里面的value排序的整个过程1.将哈希的pair放到一个向量中去2.重写sort函数,对向量进行排序3.从向量中提取结果
class Solution {
public:
static bool func(pair<int,int>& p1, pair<int,int>& p2)
{
return (p1.second>p2.second)?true:false;
}
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int> mp;
for(auto num:nums)mp[num]++;
vector<pair<int,int>> v(mp.begin(),mp.end());
sort(v.begin(),v.end(),func);
vector<int> res;
//unordered_map<int,int>::iterator iter;
//for(auto iter=mp.begin();iter!=mp.begin()+k;iter++)res.push_back(iter->first);
for(int i = 0;i<k;i++)res.push_back(v[i].first);
return res;
}
};
349. 两个数组的交集
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
set<int> st1(nums1.begin(),nums1.end());
set<int> st2(nums2.begin(),nums2.end());
vector<int> res;
for(auto s1:st1)
{
if(st2.find(s1)!=st2.end())
{res.push_back(s1);}
}
return res;
}
};
350. 两个数组的交集 II
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int,int> mp;
for(auto num:nums1)
{
if(mp.find(num)!=mp.end())
{mp[num]++;}
else
{mp[num]=1;}
}
vector<int> res;
for(auto num:nums2)
{
if(mp.find(num)!=mp.end() && mp[num]>=1)
{res.push_back(num);mp[num]--;}
}
return res;
}
};
352. 将数据流变为多个不相交区间
class SummaryRanges {
public:
/** Initialize your data structure here. */
vector<vector<int>> vt;
SummaryRanges() {
}
void addNum(int val) {
if(vt.empty())vt.push_back({val,val});
else if(val<=vt[0][0])
{
if(val==vt[0][0]-1)
{
vt[0][0]--;return;
}
else if(val+1<vt[0][0])
{
vt.insert(vt.begin(),{val,val});
}
return;
}
else if(val>=vt.back()[1])
{
if(val==vt.back()[1]+1)
{
vt.back()[1]++;return;
}
else if(val>vt.back()[1]+1)
{
vt.push_back({val,val});
}
return;
}
else
{
for(int i = 0;i<vt.size()-1;i++)
{
if(vt[i][0]<=val && val<=vt[i+1][0])
{
if(vt[i][0]==val || val==vt[i+1][0])return;
else if(vt[i][1]+1==val && val+1==vt[i+1][0])
{
vt[i][1]=vt[i+1][1];
vt.erase(vt.begin()+i+1);
return;
}
else if(vt[i][1]+1==val)
{
vt[i][1]++;return;
}
else if(vt[i+1][0]==val+1)
{
vt[i+1][0]--;return;
}
else
{
vt.insert(vt.begin()+i+1,{val,val});
return;
}
}
}
}
return;
}
vector<vector<int>> getIntervals() {
return vt;
}
};
/**
* Your SummaryRanges object will be instantiated and called as such:
* SummaryRanges* obj = new SummaryRanges();
* obj->addNum(val);
* vector<vector<int>> param_2 = obj->getIntervals();
*/
354. 俄罗斯套娃信封问题(最大递增子序列)
这是第一种做法,原理是对整体进行升序排序,然后,动态规划计算套娃信封的个数,然而这种方法在某种情况下会出现错误:某个位置不应该套,例如这个例子:
[[2,100],[3,200],[4,300],[5,500],[5,400],[5,250],[6,370],[6,360],[7,380]]
死三个信封其实可以套,但是套上就不是最大值了这里介绍一种新的思路,先对0位置进行升序,再对1位置进行降序,这样的话就成为了求最长递增系序列的问题了,现在的关键是如何实现升序加降序的操作
class Solution {
public:
int maxEnvelopes(vector<vector<int>>& envelopes) {
int len = envelopes.size();
if(len==0)return 0;
sort(envelopes.begin(), envelopes.end());
vector<int> dp(len,0);
dp[0] = 1;
int j=0;
for(int i = 1 ; i< len ;i++)
{
if(envelopes[i][0]>envelopes[j][0] && envelopes[i][1]>envelopes[j][1])
{dp[i] = dp[j]+1;j=i;}
else{dp[i]=dp[j];}
}
return dp[len-1];
}
};
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
(1)第一个参数first:是要排序的数组的起始地址。
(2)第二个参数last:是结束的地址(最后一个数据的后一个数据的地址)
(3)第三个参数comp是排序的方法:可以是从升序也可是降序。如果第三个参数不写,则默认的排序方法是从小到大排序。
比较时sort函数根据comp函数进行判断输的大小,系统默认a<b时返回真,于是从小到大排,而我的comp函数设定为a>b时返回为真,那么最终得到的排序结果也相应的从小到大变成从大到小
sort(envelopes.begin(),envelopes.end(),[](const vector<int>& a,const vector<int>& b){
return a[0]<b[0]||(a[0]==b[0]&&a[1]>b[1]);
});
或者单独写出来
static bool myfunc(vector<int> a, vector<int> b)
{
if(a[0] < b[0] && a[1] && b[1])
return true;
else
return a[0] < b[0];
}
作者:EL1S
链接:https://leetcode-cn.com/problems/russian-doll-envelopes/solution/354-e-luo-si-tao-wa-xin-feng-wen-ti-dp-zui-chang-s/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
//题解1:动态规划,时间复杂度O(n^2),空间复杂度O(n)
int maxEnvelopes_1(vector<vector<int>>& envelopes) {
if(envelopes.empty())return 0;
//先按w排序,若w相同,则按h由高到低排序;若w不同,则按w由小到大排序
sort(envelopes.begin(),envelopes.end(),[](const vector<int>& a,const vector<int>& b){
return a[0]<b[0]||(a[0]==b[0]&&a[1]>b[1]);
});
int n=envelopes.size(),res=0;
vector<int> dp(n,1);
for(int i=0;i<n;++i){
for(int j=0;j<i;++j){
if(envelopes[j][1]<envelopes[i][1]){
dp[i]=max(dp[i],dp[j]+1);
}
}
res=max(res,dp[i]);
}
return res;
}
//优化:动态规划+二分法,时间复杂度O(nlogn),空间复杂度O(n)
int maxEnvelopes(vector<vector<int>>& envelopes){
if(envelopes.empty())return 0;
//先按w排序,若w相同,则按h由高到低排序;若w不同,则按w由小到大排序
sort(envelopes.begin(),envelopes.end(),[](const auto& a,const auto& b){
return a[0]<b[0]||(a[0]==b[0]&&a[1]>b[1]);
});
vector<int> dp;
for(auto& en:envelopes){
int idx=lower_bound(dp.begin(),dp.end(),en[1])-dp.begin();
if(idx>=dp.size()){
dp.emplace_back(en[1]);
}
else{
dp[idx]=en[1];
}
}
return dp.size();
}
};
作者:xiaoneng
链接:https://leetcode-cn.com/problems/russian-doll-envelopes/solution/cdong-tai-gui-hua-jiang-er-wei-shu-zu-jiang-wei-ch/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
355. 设计推特
bool operator<(const pair<int, int>& a, const pair<int, int>& b) {
return a.first < b.first;
}
class Twitter {
public:
int timeStamp;
unordered_map<int, unordered_set<int>> subMap;
unordered_map<int, vector<pair<int, int>>> postMap;
/** Initialize your data structure here. */
Twitter() {
timeStamp = 0;
}
/** Compose a new tweet. */
void postTweet(int userId, int tweetId) {
postMap[userId].push_back({ ++timeStamp , tweetId });
}
/** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */
vector<int> getNewsFeed(int userId) {
vector<int> result;
priority_queue<pair<int, int>> myQueue;
subMap[userId].insert(userId);
for (int i : subMap[userId])
for (pair<int, int>& p : postMap[i])
myQueue.push(p);
while (!myQueue.empty() && result.size() < 10){
result.push_back(myQueue.top().second);
myQueue.pop();
}
return result;
}
/** Follower follows a followee. If the operation is invalid, it should be a no-op. */
void follow(int followerId, int followeeId) {
subMap[followerId].insert(followeeId);
}
/** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */
void unfollow(int followerId, int followeeId) {
subMap[followerId].erase(followeeId);
}
};
作者:wpn-zju
链接:https://leetcode-cn.com/problems/design-twitter/solution/c-unordered_map-priority_queue-by-wpn-zju/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Twitter {
public:
deque<pair<int,int>> cache;
unordered_map<int,vector<int>> mp;
/** Initialize your data structure here. */
Twitter() {
}
/** Compose a new tweet. */
void postTweet(int userId, int tweetId) {
cache.push_front(make_pair(userId,tweetId));
return;
}
/** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */
vector<int> getNewsFeed(int userId) {
vector<int> res;
vector<int> ID;
ID.push_back(userId);
if(mp.find(userId)!=mp.end())
{
for(auto i:mp[userId])ID.push_back(i);
}
for(int i =0;i<cache.size();i++)
{
if(find(ID.begin(),ID.end(),cache[i].first)!=ID.end()){res.push_back(cache[i].second);}
if(res.size()==10)break;
}
return res;
}
/** Follower follows a followee. If the operation is invalid, it should be a no-op. */
void follow(int followerId, int followeeId) {
mp[followerId].push_back(followeeId);
return;
}
/** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */
void unfollow(int followerId, int followeeId) {
for(auto iter=mp[followerId].begin();iter!=mp[followerId].end();iter++)
{
if(*iter==followeeId){mp[followerId].erase(iter);break;}
}
return;
}
};
/**
* Your Twitter object will be instantiated and called as such:
* Twitter* obj = new Twitter();
* obj->postTweet(userId,tweetId);
* vector<int> param_2 = obj->getNewsFeed(userId);
* obj->follow(followerId,followeeId);
* obj->unfollow(followerId,followeeId);
*/
357. 计算各个位数不同的数字个数
/*
一位数时 10
二位数时 9*9(首位可选1~9 = 9种可能 ;第二位0~10 - 首位的值 = 9种可能)
三位数时 9*9*8
对于n 把以上加起来就是答案了
*/
int countNumbersWithUniqueDigits(int n) {
if(n==0) return 1;
int res = 10,num = 9*9;
for(int i = 2; i <= min(n,10); i++) res += num, num = num*(10-i);
return res;
}
作者:zeroac
链接:https://leetcode-cn.com/problems/count-numbers-with-unique-digits/solution/c-gui-lu-by-zeroac/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
365. 水壶问题
class Solution {
public:
bool canMeasureWater(int x, int y, int z) {
if(x+y<z)return false;
if(x==0 )return z==y;
if(y==0)return z==x;
return z%gcd(x,y)==0;
}
};
367. 有效的完全平方数
注意溢出的处理,乘变除还要转换类型
class Solution {
public:
bool isPerfectSquare(int num) {
if(num==1)return true;
int left = 1,right = num/2+1;
while(left<right)
{
int mid = left+(right-left)/2;
if((double)num/mid==mid)return true;
if((double)num/mid>mid)
{
left = mid+1;
}
else
{
right = mid;
}
}
return false;
}
};
368. 最大整除子集(路径记录**)
dfs
class Solution {
public:
vector<int> res;
int m = 0;
vector<int> path;
bool isok(vector<int>a, int b)
{
for (int i = 0; i < a.size(); i++)
{
if (a[i] == 1 || b == 1)continue;
if (a[i] % b != 0 && b % a[i] != 0)return false;
}
return true;
}
void dfs(int p, vector<int> nums)
{
if (m < path.size())
{
m = path.size();
res = path;
}
if (p == nums.size())
{
return;
}
if (isok(path, nums[p]))
{
path.push_back(nums[p]);
dfs(p + 1, nums);
path.pop_back();
}
dfs(p + 1, nums);
}
vector<int> largestDivisibleSubset(vector<int> nums) {
dfs(0, nums);
return res;
}
};
class Solution {
public:
vector<int>res;
vector<int> largestDivisibleSubset(vector<int>& nums) {
int len=nums.size();
if(len==0) return res;
sort(nums.begin(),nums.end());
vector<int>path(len,-1);
vector<int>dp(len,1);
int max_num=1,max_index=0;
for(int i=0;i<len;i++){
for(int j=0;j<i;j++){
if(nums[i]%nums[j]==0&&dp[j]+1>dp[i]){
dp[i]=dp[j]+1;
path[i]=j;
}
}
if(max_num<dp[i]){
max_num=dp[i];
max_index=i;
}
}
do{
res.push_back(nums[max_index]);
max_index=path[max_index];
}while(max_index!=-1);
reverse(res.begin(),res.end());
return res;
}
};
作者:chen-ze-hua-c
链接:https://leetcode-cn.com/problems/largest-divisible-subset/solution/c-dong-tai-gui-hua-by-chen-ze-hua-c-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
369. 给单链表加一
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* plusOne(ListNode* head) {
auto head1 = new ListNode(1);
head1->next = head;
auto fast = head1;
auto slow = head1;
while(1)
{
while(fast && fast->val==9)
{
fast = fast->next;
}
if(fast)
{
slow = fast;
fast = fast->next;
}
else break;
}
if(slow==head1)
{
slow = slow->next;
while(slow)
{
slow->val=0;
slow = slow->next;
}
return head1;
}
else
{
slow->val++;
slow = slow->next;
while(slow)
{
slow->val=0;
slow = slow->next;
}
return head1->next;
}
}
};
371. 两整数之和(位运算)
while (b)
{
auto carry = ((unsigned int ) (a & b))<<1 ; // 记录a+b的进位,直到进位为0是退出
a = a^b; //结果相加
b = carry; //循环
}
return a;
作者:zi-lun
链接:https://leetcode-cn.com/problems/sum-of-two-integers/solution/cshi-xian-xiang-jie-by-zi-lun/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
370. 区间加法
class Solution {
public:
vector<int> getModifiedArray(int length, vector<vector<int>>& updates) {
vector<int> res(length+1,0);
for(auto&u:updates)
{
res[u[0]+1] += u[2];
if(u[1]+1+1<=length)res[u[1]+1+1] -= u[2];
}
vector<int> dp(length,0);
for(int i = 0;i<length;i++)
{
if(i==0)
{
dp[i]=res[i+1];continue;
}
dp[i] = dp[i-1] + res[i+1];
}
return dp;
}
};
371. 两整数之和
class Solution {
public:
int getSum(int a, int b) {
int x = ((unsigned int)a^b);
int y = (((unsigned int)(a&b))<<1);
while(y)
{
auto t = (((unsigned int)(x&y))<<1);
x = (x^y);
y = t;
}
return x;
}
};
373. 查找和最小的K对数字(堆排序(优先队列)****************)
class Solution {
public:
vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
map<int,vector<vector<int>>> mp;
for(auto&i:nums1)
{
for(auto&j:nums2)
{
mp[i + j].push_back({i,j});
}
}
vector<vector<int>> res;
int i =0;
bool b = false;
for(auto &m:mp)
{
for(auto&m1:m.second)
{
res.push_back(m1);i++;
if(i>=k){b = true;break;}
}
if(b)break;
}
return res;
}
};
class Solution {
public:
static bool cmp(pair<int,vector<int>>a, pair<int,vector<int>>b)
{
return a.first<b.first;
}
vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
vector<pair<int,vector<int>>> vt;
for(auto&i:nums1)
{
for(auto&j:nums2)
{
vector<int> a = {i,j};
pair<int,vector<int>> b = {i+j,a};
vt.push_back(b);
}
}
sort(vt.begin(),vt.end(),cmp);
vector<vector<int>> res;
for(int i = 0;i<min((int)vt.size(),k);i++)
{
res.push_back(vt[i].second);
}
return res;
}
};
一开始考虑的是建立一个哈希表,但是发现key不能是pair,所以这里不能使用哈希,但是优先队列里面是可以放pair结构的,先将前k个放入,之后如果小于栈顶,则将其放入,维护一个自定义的大顶堆
class Solution {
public:
struct cmp{
bool operator ()(pair<int, int> &a, pair<int, int> &b) {
return a.first+a.second<b.first+b.second;
}
};
vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
priority_queue<pair<int,int>,vector<pair<int,int>>,cmp>q;
vector<vector<int>>res;
for(int i=0;i<nums1.size();i++){
for(int j=0;j<nums2.size();j++){
if(q.size()<k)
q.push({nums1[i],nums2[j]});
else if(nums1[i]+nums2[j]<q.top().first+q.top().second){
q.pop();
q.push({nums1[i],nums2[j]});
}
}
}
while(!q.empty()){
pair<int,int> top=q.top();
res.push_back({top.first,top.second});
q.pop();
}
return res;
}
};
作者:user3350r
链接:https://leetcode-cn.com/problems/find-k-pairs-with-smallest-sums/solution/c-you-xian-dui-lie-da-ding-dui-by-user3350r/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
上面这个不转向量的优先队列有几点要注意的地方
1.不写成向量直接写cmp函数要先写一个结果体,里面套一个bool的operator函数
2.这道题是要建一个大顶堆,把最大的放在堆顶,要注意写cmp的时候要写成小于好,因为是求前k个最小,要按更大的一个逻辑来
这道题统计频率意义不大,所以不用哈希,如果用堆排序的话用的也是自动排序的功能,如果在写堆排序的时候像哈希那样转成向量再实现的话既无法实现也没意义,不如直接就放到vector里并重写sort函数,所以这道题要么直接使用vector要么就使用堆,然后注意不转向量的堆排序需要把cmp函数写成一个结果体的形式
下面是直接使用vector的做法,可能这才是最简单的方式
class Solution {
public:
vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
vector<vector<int>> sums;
for(size_t i=0;i<nums1.size();++i){
for(size_t j=0;j<nums2.size();++j){
sums.push_back(vector<int>{nums1[i],nums2[j]});
}
}
std::sort(sums.begin(), sums.end(), [](vector<int>& l, vector<int>& r){
return ((l[0]+l[1]) < (r[0]+r[1]));
});
if(static_cast<size_t>(k) > sums.size()) return sums;
vector<vector<int>> sums_truc(sums.begin(), sums.begin()+k);
return sums_truc;
}
};
作者:user2473E
链接:https://leetcode-cn.com/problems/find-k-pairs-with-smallest-sums/solution/cun-chu-pai-xu-jie-qu-by-user2473e/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这是对需要对复杂结构进行排序的用法总结
1.需要统计次数只能用哈希的就先用哈希,排序时可以直接用结构体cmp排序也可以转成向量再用函数cmp排序
2.如果不是一定要使用哈希功能的,能使用vector排序的都建议使用vector因为这是能容纳类型较多的容器,而且可能其他类型的参数比较难写
374. 猜数字大小(二分法)
/**
* Forward declaration of guess API.
* @param num your guess
* @return -1 if num is lower than the guess number
* 1 if num is higher than the guess number
* otherwise return 0
* int guess(int num);
*/
class Solution {
public:
int guessNumber(int n) {
int left =1,right = n;
while(left<right)
{
long mid = left+(right-left)/2;
if(guess(mid)==0)return mid;
else if(guess(mid)==1)
{left=mid+1;}
else
{right=mid;}
}
return left;
}
};
376. 摆动序列
int wiggleMaxLength(vector<int>& nums) {
if(nums.empty())return 0;
int len = nums.size();
int pre = 0;
int res = 1;
for(int i =1;i<len;i++)
{
if(nums[i]==nums[i-1])continue;
int cur = nums[i]>nums[i-1]?1:-1;
if(pre!=cur)
{
res++;
pre = cur;
}
}
return res;
}
377. 组合总和 Ⅳ(dfs,dp)
使用dfs会超时,但是属于典型的dfs思路
class Solution {
private:
int res=0;
int sum = 0;
public:
void dfs(vector<int>& nums, int target, int& sum,int& res)
{
if (sum == target) { res++; return; }
if (sum > target)return;
for (int i = 0; i < nums.size(); i++)
{
sum += nums[i];
dfs(nums, target, sum,res);
sum -= nums[i];
}
}
int combinationSum4(vector<int>& nums, int target) {
dfs(nums, target, sum, res);
return res;
}
};
dp
class Solution {
public int combinationSum4(int[] nums, int target) {
//dfs会超时
//使用dp数组,dp[i]代表组合数为i时使用nums中的数能组成的组合数的个数
//别怪我写的这么完整
//dp[i]=dp[i-nums[0]]+dp[i-nums[1]]+dp[i=nums[2]]+...
//举个例子比如nums=[1,3,4],target=7;
//dp[7]=dp[6]+dp[4]+dp[3]
//其实就是说7的组合数可以由三部分组成,1和dp[6],3和dp[4],4和dp[3];
int[]dp=new int[target+1];
//是为了算上自己的情况,比如dp[1]可以由dp【0】和1这个数的这种情况组成。
dp[0]=1;
for(int i=1;i<=target;i++)
{
for(int num:nums)
{
if(i>=num)
{
dp[i]+=dp[i-num];
}
}
}
return dp[target];
}
}
注意的问题是背包比当前的大才可以,小的话不行,然后要注意初值,
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
//完全背包,而且计算顺序,则物品在里面
vector<long long> dp(target+1,0);
dp[0]=1;
for(int i = 1; i<= target ;i++)
{
for(auto num:nums)
{
if(i>=num)
{dp[i] = dp[i] + dp[i-num];}
}
}
return dp[target];
}
};
378. 有序矩阵中第K小的元素
如果返回值等于k时直接返回mid,这个mid可能不会再矩阵中,但是范围二分就可以;这种递增矩阵有从坐下到右上查找的特点
class Solution {
public:
bool check(vector<vector<int>>& matrix, int mid, int k, int n) {
int i = n - 1;
int j = 0;
int num = 0;
while (i >= 0 && j < n) {
if (matrix[i][j] <= mid) {
num += i + 1;
j++;
} else {
i--;
}
}
return num >= k;
}
int kthSmallest(vector<vector<int>>& matrix, int k) {
int n = matrix.size();
int left = matrix[0][0];
int right = matrix[n - 1][n - 1];
while (left < right) {
int mid = left + ((right - left) >> 1);
if (check(matrix, mid, k, n)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/solution/you-xu-ju-zhen-zhong-di-kxiao-de-yuan-su-by-leetco/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
379. 电话目录管理系统
class PhoneDirectory {
public:
unordered_set<int> st;
/** Initialize your data structure here
@param maxNumbers - The maximum numbers that can be stored in the phone directory. */
PhoneDirectory(int maxNumbers) {
for(int i = 0;i<maxNumbers;i++)
{
st.insert(i);
}
}
/** Provide a number which is not assigned to anyone.
@return - Return an available number. Return -1 if none is available. */
int get() {
if(st.empty())return -1;
auto iter = st.begin();
int temp = *iter;
st.erase(iter);
return temp;
}
/** Check if a number is available or not. */
bool check(int number) {
return st.find(number)!=st.end();
}
/** Recycle or release a number. */
void release(int number) {
st.insert(number);
}
};
/**
* Your PhoneDirectory object will be instantiated and called as such:
* PhoneDirectory* obj = new PhoneDirectory(maxNumbers);
* int param_1 = obj->get();
* bool param_2 = obj->check(number);
* obj->release(number);
*/
380. 常数时间插入、删除和获取随机元素(next函数)
class RandomizedSet {
public:
/** Initialize your data structure here. */
unordered_set<int> st;
RandomizedSet() {
}
/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
bool insert(int val) {
if(st.find(val)!=st.end())return false;
st.insert(val);
return true;
}
/** Removes a value from the set. Returns true if the set contained the specified element. */
bool remove(int val) {
if(st.find(val)==st.end())return false;
st.erase(val);
return true;
}
/** Get a random element from the set. */
int getRandom() {
auto iter = st.begin();
int a = rand()%st.size();
return *next(iter,a);
}
};
/**
* Your RandomizedSet object will be instantiated and called as such:
* RandomizedSet* obj = new RandomizedSet();
* bool param_1 = obj->insert(val);
* bool param_2 = obj->remove(val);
* int param_3 = obj->getRandom();
*/
382. 链表随机节点
class Solution {
public:
/** @param head The linked list's head.
Note that the head is guaranteed to be not null, so it contains at least one node. */
Solution(ListNode* head): head(head) {
}
/** Returns a random node's value. */
int getRandom() {
int i=2;
ListNode* cur = head->next;
int val = head->val;
while(cur != nullptr) {
if(rand() % i + 1 == 1) val = cur->val; //第 i 节点以 1/i 概率替换当前值
i++;
cur = cur->next;
}
return val;
}
private:
ListNode* head;
};
作者:li-zi-he
链接:https://leetcode-cn.com/problems/linked-list-random-node/solution/zhong-ju-si-wei-by-li-zi-he/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
383. 赎金信
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
unordered_map<char,int> mp;
for(auto m:magazine)
{
if(mp.find(m)==mp.end())
{mp[m]=1;}
else
{mp[m]++;}
}
for(auto r:ransomNote)
{
if(mp.find(r)==mp.end())
{return false;}
else
{
if(mp[r]==0){return false;}
else{mp[r]--;}
}
}
return true;
}
};
386. 字典序排数
map
class Solution {
public:
vector<int> lexicalOrder(int n) {
map<string,int> mp;
for(int i =1;i<=n;i++)
{
mp[to_string(i)]=i;
}
vector<int> res;
for(auto&m:mp)
{
res.push_back(m.second);
}
return res;
}
};
dfs
class Solution {
public:
vector<int> res;
void dfs(int k,int n)
{
if(k>n)return;
if(k!=0)res.push_back(k);
for(int i = 0;i<=9;i++)
{
if(k*10 + i>0)
{
int t = k;
k = k*10+i;
dfs(k,n);
k = t;
}
}
}
vector<int> lexicalOrder(int n) {
dfs(0,n);
return res;
}
};
389. 找不同
ascii码之差
class Solution {
public:
char findTheDifference(string s, string t) {
int ans = 0;
for (char ch : t) ans += ch;
for (char ch : s) ans -= ch;
return (char)ans;
}
};
作者:Gary_coding
链接:https://leetcode-cn.com/problems/find-the-difference/solution/c-zhong-gui-zhong-ju-de-0msjie-fa-bao-li-by-gary-5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
异或
class Solution {
public:
char findTheDifference(string s, string t) {
char res=0;
for(int i=0;i<s.size();i++)
{
res^=s[i];
}
for(int i=0;i<t.size();i++)
{
res^=t[i];
}
return res;
}
};
作者:haydenmiao
链接:https://leetcode-cn.com/problems/find-the-difference/solution/yi-huo-zui-zhong-jie-guo-ji-wei-tian-jia-de-zhi-by/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
392. 判断子序列
class Solution {
public:
bool isSubsequence(string s, string t) {
if(s.empty())return true;
if(t.empty())return false;
int lens = s.size();
int lent = t.size();
vector<vector<bool>> dp(lens,vector<bool>(lent,false));
for(int i = 0;i<lent;i++)
{
if(t[i]==s[0])dp[0][i]=true;
else if(i==0)dp[0][i]=false;
else dp[0][i]=dp[0][i-1];
}
for(int i = 1;i<lens;i++)
{
for(int j =1;j<lent;j++)
{
if(s[i]==t[j])dp[i][j]=dp[i-1][j-1];
else dp[i][j]=dp[i][j-1];
}
}
return dp[lens-1][lent-1];
}
};
class Solution {
public:
bool isSubsequence(string s, string t) {
//转变为求公共子序列问题
string r = s;
s = t;
t = r;
int lent = t.size();
int lens = s.size();
vector<vector<int>> vt(lent+1, vector<int>(lens+1,0));
for(int i = 1 ;i<=lent ;i++)
{
for( int j = 1 ; j<=lens ;j++)
{
if(t[i-1]==s[j-1])vt[i][j] = vt[i-1][j-1]+1;
else vt[i][j]=max(vt[i-1][j],vt[i][j-1]);
}
}
return lent==vt[lent][lens];
}
};
双指针确实更好
代码块class Solution
{
public:
bool isSubsequence(string s, string t)
{
int tag = 0;
//如果s为空,也是对的
if(s.empty())
return true;
//一个个扫描
for(int i = 0; i < t.size(); i++)
{
if(t[i] == s[tag])
{
tag++;
if(tag >= s.size())
return true;
}
}
return false;
}
};
作者:lu-guo-de-feng-2
链接:https://leetcode-cn.com/problems/is-subsequence/solution/zui-jian-ji-de-c-by-lu-guo-de-feng-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
394. 字符串解码(好)
string decodeString(string s) {
int i = 0;
int len = s.size();
string res = "";
while (i < len)
{
if (isdigit(s[i]))
{
stack<string> st;
int j = i;
while (i < len && isdigit(s[i]))i++;
int x = stoi(s.substr(j, i - j));
int count = 0;
j = i;
while (i < len)
{
if (s[i] == '[')count++;
if (s[i] == ']')count--;
if (count == 0)break;
i++;
}
auto temp = s.substr(j+1, i - j-1);
string t = decodeString(temp);
while (x--)res += t;
i++;
}
else if (isalpha(s[i]))
{
int j = i;
while (i < len && isalpha(s[i]))i++;
res += s.substr(j, i - j);
}
}
return res;
}
395. 至少有K个重复字符的最长子串
class Solution {
public:
int res=0;
void dfs(string &s,int k,int l,int r){
if(r-l+1<k) return ;
map<char,int>mp;
for(int i=l;i<=r;i++){
mp[s[i]]++;
}
int ll=l;
for(int i=l;i<=r;i++){
if(mp[s[i]]<k){
dfs(s,k,ll,i-1);
ll=i+1;
}
}
if(ll!=l&&ll!=r) dfs(s,k,ll,r);
if(ll==l) res=max(res,r-l+1);
return ;
}
int longestSubstring(string s, int k){
dfs(s,k,0,s.size()-1);
return res;
}
};
作者:shi-jie-na-you-zhen-qing
链接:https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters/solution/395-zhi-shao-you-kge-zhong-fu-zi-fu-de-zui-chang-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
int longestSubstring(string s, int k) {
if(s=="") return 0;
map<int, int> counts;
for(auto w:s){
auto it = counts.find(w);
if(it==counts.end()) counts[w] = 1;
else counts[w]++;
}
bool isAll = true;
for(auto it = counts.begin();it!=counts.end();it++){
if(it->second<k){
isAll = false;
break;
}
}
if(isAll) return s.size();
int maxCounts = 0;
for(int i=0;i<s.size();i++){
int start = i, nums = 0;
while(i<s.size()&&counts[s[i]]>=k) {
nums++;
i++;
}
if(nums>0) maxCounts = max(longestSubstring(s.substr(start, nums), k), maxCounts);
}
return maxCounts;
}
};
作者:shelro
链接:https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters/solution/c-fen-zhi-fa-100-by-shelro/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
397. 整数替换
class Solution {
public:
int dfs(long int n)
{
if(n == 1) return 0;
if(n % 2 == 0) return 1 + dfs(n / 2);
return min(1 + dfs(n + 1), 1 + dfs(n - 1));
}
int integerReplacement(int n) {
return dfs(n);
}
};
作者:css_shuai
链接:https://leetcode-cn.com/problems/integer-replacement/solution/jiu-dfsyi-xia-ba-by-css_shuai/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
int integerReplacement(int n) {
if (n == INT_MAX) // 处理溢出,也可以直接用long tmp = n;
return 32;
int count = 0;
while (n != 1) {
if ((n & 1) == 0) { // 偶数直接右移
n>>=1;
}else {
// 奇数 01减一,11加1,特殊情况n=3也是减1
n += ((n & 2) == 0 || n == 3)? -1:1;
}
count++;
}
return count;
}
};
作者:ma-xing
链接:https://leetcode-cn.com/problems/integer-replacement/solution/wei-yun-suan-by-ma-xing/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
398. 随机数索引
class Solution {
private int[] nums;
public Solution(int[] nums) {
this.nums = nums;
}
public int pick(int target) {
Random r = new Random();
int n = 0;
int index = 0;
for(int i = 0;i < nums.length;i++)
if(nums[i] == target){
//我们的目标对象中选取。
n++;
//我们以1/n的概率留下该数据
if(r.nextInt() % n == 0) index = i;
}
return index;
}
}
作者:an-xin-9
链接:https://leetcode-cn.com/problems/random-pick-index/solution/xu-shui-chi-chou-yang-wen-ti-by-an-xin-9/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
unordered_map<int,vector<int>> mp;
Solution(vector<int>& nums) {
for(int i = 0;i<nums.size();i++)
{
mp[nums[i]].push_back(i);
}
}
int pick(int target) {
auto a = mp[target];
int i = rand()%a.size();
return a[i];
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution* obj = new Solution(nums);
* int param_1 = obj->pick(target);
*/
399. 除法求值(并查集)
class Solution {
public:
unordered_map<int,pair<int,double>>father;
int Find(int x){
if(x != father[x].first){
int t = father[x].first;
father[x].first = Find(father[x].first);
father[x].second *= father[t].second;
return father[x].first;
}
return x;
}
void Union(int e1,int e2,double result){
int f1 = Find(e1);
int f2 = Find(e2);
if(f1 != f2){
father[f2].first = f1;
father[f2].second = father[e1].second * result / father[e2].second;
}
}
vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
vector<double> ans;
unordered_map<string,int> now;
int numString = 1;
for(int i = 0 ; i < equations.size() ; i++){
int e1,e2;
if(now[equations[i][0]] == 0){
now[equations[i][0]] = numString++;
father[numString-1].first = numString-1;
father[numString-1].second = 1;
}
if(now[equations[i][1]] == 0){
now[equations[i][1]] = numString++;
father[numString-1].first = numString-1;
father[numString-1].second = 1;
}
e1 = now[equations[i][0]];
e2 = now[equations[i][1]];
Union(e1,e2,values[i]);
}
for(int i = 0 ; i < queries.size() ; i++){
if(now[queries[i][0]] == 0 || now[queries[i][1]] == 0){
ans.push_back(-1.0);
continue;
}
int e1 = now[queries[i][0]];
int e2 = now[queries[i][1]];
int f1 = Find(e1);
int f2 = Find(e2);
if(f1 != f2){
ans.push_back(-1.0);
}
else{
double temp = father[e1].second;
double temp2 = father[e2].second;
ans.push_back(temp2/temp);
}
}
return ans;
}
};
作者:guduhuanzhelz666
链接:https://leetcode-cn.com/problems/evaluate-division/solution/dai-quan-bing-cha-ji-fei-chang-hao-de-dai-quan-bin/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。