Skip to content

Commit b64aa63

Browse files
committed
更新leetcode 300-319未上锁算法
1 parent 24c690d commit b64aa63

16 files changed

+226
-91
lines changed

cpp/leetcode/300. longest-increasing-subsequence.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "public.h"
22

3+
/*
34
//44ms, 71.18%
45
//DP problem
56
//O(n^2), 理论上可以结合二分查找降至O(nlongn), 待优化
@@ -30,3 +31,25 @@ class Solution {
3031
}
3132
}
3233
};
34+
*/
35+
36+
//4ms, 96.72%
37+
//DP+二分
38+
//维持一个有序变长DP序列: 内部已排序, 长度表示当前最长上升子序列(但内容却不一定完全合法)
39+
//对每个新的num, 如果当前插入DP位置在末尾则DP长度+1,并插入, 否则替换掉可以插入的位置
40+
//最终返回DP的长度
41+
42+
class Solution {
43+
public:
44+
int lengthOfLIS(vector<int>& nums) {
45+
vector<int> dp;
46+
47+
for (auto& num : nums)
48+
{
49+
vector<int>::iterator iter = lower_bound(dp.begin(), dp.end(), num);
50+
if (iter == dp.end()) dp.emplace_back(num);
51+
else dp[iter - dp.begin()] = num;
52+
}
53+
return dp.size();
54+
}
55+
};

cpp/leetcode/301. remove-invalid-parentheses.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#include "public.h"
22

3-
//20ms, 46.26%
3+
//0ms, 100%
44
//先统计最少需要去掉的左括号和右括号, 然后递归回溯
55

66
class Solution {
77
private:
88
unordered_set<string> res;
99
void recurse(const string& s, int index, int left_count, int right_count,
10-
int left_rem, int right_rem, string expr)
10+
int left_rem, int right_rem, string& expr)
1111
{
1212
if (index == s.size())
1313
{
@@ -17,11 +17,12 @@ class Solution {
1717
else
1818
{
1919
//直接丢弃当前的括号, 向内递归
20-
if ((s[index] == '(' && left_rem > 0) || (s[index] == ')' && right_rem > 0))
21-
{
22-
recurse(s, index + 1, left_count, right_count, left_rem - (s[index] == '('),
23-
right_rem - (s[index] == ')'), expr);
24-
}
20+
if ((s[index] == '(' && left_rem > 0))
21+
recurse(s, index + 1, left_count, right_count, left_rem - 1,
22+
right_rem, expr);
23+
if ((s[index] == ')' && right_rem > 0))
24+
recurse(s, index + 1, left_count, right_count, left_rem,
25+
right_rem - 1, expr);
2526

2627
//记录当前内容
2728
expr.push_back(s[index]);
@@ -56,7 +57,8 @@ class Solution {
5657
if (left == 0) right++;
5758
else left--;
5859

59-
recurse(s, 0, 0, 0, left, right, "");
60+
string exp = "";
61+
recurse(s, 0, 0, 0, left, right, exp);
6062
vector<string> returnres(res.begin(), res.end());
6163
return returnres;
6264
}
@@ -66,7 +68,7 @@ class Solution {
6668
int main()
6769
{
6870
Solution* s = new Solution();
69-
vector<string> res = s->removeInvalidParentheses("(a)())()");
71+
vector<string> res = s->removeInvalidParentheses("()())()");
7072
return 0;
7173
}
7274
*/
Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,20 @@
11
#include "public.h"
22

3-
//36ms, 98.20%
3+
//36ms, 94.90%
44
//设置一个vector, 应当存入下标0至当前下标的和
55

66
class NumArray {
77
private:
88
vector<int> vnums;
99
public:
1010
NumArray(vector<int>& nums) {
11-
vnums.reserve(nums.size());
12-
int sum = 0;
13-
for (int i = 0; i < nums.size(); ++i)
14-
{
15-
sum += nums[i];
16-
vnums[i] = sum;
17-
}
11+
vnums.reserve(nums.size() + 1);
12+
vnums[0] = 0;
13+
for (int i = 1; i <= nums.size(); ++i)
14+
vnums[i] = vnums[i - 1] + nums[i - 1];
1815
}
1916

2017
int sumRange(int i, int j) {
21-
if (i == 0)
22-
{
23-
return vnums[j];
24-
}
25-
else
26-
{
27-
return vnums[j] - vnums[i - 1];
28-
}
18+
return vnums[j + 1] - vnums[i];
2919
}
3020
};
31-
32-
/**
33-
* Your NumArray object will be instantiated and called as such:
34-
* NumArray* obj = new NumArray(nums);
35-
* int param_1 = obj->sumRange(i,j);
36-
*/
Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "public.h"
22

3-
//32ms, 91.48%
3+
//24ms, 98.46%
44
//和上一题差不多一个意思
55
//变成4个矩形
66

@@ -14,13 +14,6 @@ class NumMatrix {
1414
vector<int> temp(matrix[0].size() + 1);
1515
prev.resize(matrix.size() + 1, vector<int>(matrix[0].size() + 1, 0));
1616

17-
/*
18-
for (int i = 0; i < matrix[0].size(); ++i)
19-
prev[0][i] = 0;
20-
for (int i = 1; i < matrix.size(); ++i)
21-
prev[i][0] = 0;
22-
*/
23-
2417
for (int row = 1; row <= matrix.size(); ++row)
2518
{
2619
int presum = 0;
@@ -36,9 +29,3 @@ class NumMatrix {
3629
return prev[row2 + 1][col2 + 1] - prev[row2 + 1][col1] - prev[row1][col2 + 1] + prev[row1][col1];
3730
}
3831
};
39-
40-
/**
41-
* Your NumMatrix object will be instantiated and called as such:
42-
* NumMatrix* obj = new NumMatrix(matrix);
43-
* int param_1 = obj->sumRegion(row1,col1,row2,col2);
44-
*/

cpp/leetcode/306. additive-number.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
#include "public.h"
22

3-
//4ms, 91.58%
3+
//4ms, 75.96%
44
//DFS
55

66
class Solution {
77
public:
88
bool isAdditiveNumber(string num) {
9-
if (num.size() <= 2) return false;
10-
for (int i = 1; 2 * i <= num.size(); i++) {
11-
for (int j = 1; i + 2 * j <= num.size(); j++) {
9+
int nSize = num.size();
10+
if (nSize <= 2) return false;
11+
for (int i = 1; 2 * i <= nSize; i++) {
12+
for (int j = 1; i + 2 * j <= nSize; j++) {
1213
if (dfs(num, str2int(num.substr(0, i)), str2int(num.substr(i, j)), i + j, j))
1314
return true;
1415
}
@@ -17,10 +18,11 @@ class Solution {
1718
return false;
1819
}
1920
private:
20-
bool dfs(const string& num, long pre, long prepre, int i, int len) {
21-
if (i == num.size()) return true;
22-
if ((i > num.size())) return false;
23-
for (int j = len; j <= num.size(); j++) {
21+
bool dfs(string const& num, long pre, long prepre, int i, int len) {
22+
int nSize = num.size();
23+
if (i == nSize) return true;
24+
if (i > nSize) return false;
25+
for (int j = len; j <= nSize; j++) {
2426
long cur = str2int(num.substr(i, j));
2527
if (cur == -1) return false;
2628
if (cur == pre + prepre && dfs(num, prepre, cur, i + j, j))
@@ -29,10 +31,10 @@ class Solution {
2931
return false;
3032
}
3133

32-
long str2int(const string& s) {
34+
long str2int(string const& s) {
3335
if (s.size() > 1 && s[0] == '0') return -1;
3436
long sum = 0;
35-
for (auto c : s) {
37+
for (auto& c : s) {
3638
if (sum >= LONG_MAX / 10) return -1;
3739
sum = sum * 10 + c - '0';
3840
}

cpp/leetcode/307. range-sum-query-mutable.cpp

Lines changed: 83 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,75 @@
11
#include "public.h"
22

3-
//224ms, 24.73%, 待优化
3+
//40ms, 91.86%
4+
//分段求和, 伪线段树
5+
6+
class NumArray {
7+
private:
8+
vector<int> sums;
9+
vector<int> cpNums;
10+
int segSize;
11+
int sSize;
12+
13+
public:
14+
NumArray(vector<int>& nums) {
15+
int nSize = nums.size();
16+
if (nSize == 0) return;
17+
18+
cpNums = nums;
19+
segSize = (int)sqrt(nSize);
20+
sSize = nSize / segSize;
21+
sums.resize(sSize);
22+
//初始化sums: 下标i 存放 nums中的[segSize*(i-1): segSize*i)的和
23+
for (int index = 0; index < sSize; ++index)
24+
{
25+
sums[index] = accumulate(nums.begin() + segSize * index,
26+
nums.begin() + segSize * (index + 1),
27+
0);
28+
}
29+
}
30+
31+
void update(int i, int val) {
32+
//求i的segSize的整数倍数, 向下取整
33+
int mulIndex = i / segSize;
34+
if (mulIndex != sSize) sums[mulIndex] += val - cpNums[i];
35+
cpNums[i] = val;
36+
}
37+
38+
int sumRange(int i, int j) {
39+
//按区间求和
40+
//求i/j的segSize整数倍数, 向上/下取整
41+
//sti是实际连续求和段的起始sums坐标, enj是结束坐标
42+
int muli, mulj, sti, enj;
43+
int res = 0;
44+
45+
muli = i / segSize;
46+
if (i%segSize != 0) //例如: segSize:3, i:1, j=7; 一共是 012 345 678
47+
{
48+
res += accumulate(cpNums.begin() + i, cpNums.begin() + (muli + 1)*segSize, 0);
49+
sti = muli + 1;
50+
}
51+
else sti = muli;
52+
53+
mulj = j / segSize;
54+
if ((j + 1) % segSize != 0)
55+
{
56+
res += accumulate(cpNums.begin() + mulj * segSize, cpNums.begin() + j + 1, 0);
57+
enj = mulj - 1;
58+
}
59+
else enj = mulj;
60+
61+
if (sti == enj + 2) return res - sums[enj + 1];
62+
else if (sti <= (enj + 1))
63+
{
64+
return res + accumulate(sums.begin() + sti, sums.begin() + enj + 1, 0);
65+
}
66+
else return -99999; //dump
67+
}
68+
};
69+
70+
/*
71+
//224ms, 24.73%
72+
//纯暴力
473
//vector<int>保存下标0至当前的元素和
574
675
class NumArray {
@@ -32,10 +101,17 @@ class NumArray {
32101
else return sums[j] - sums[i - 1];
33102
}
34103
};
104+
*/
35105

36-
/**
37-
* Your NumArray object will be instantiated and called as such:
38-
* NumArray* obj = new NumArray(nums);
39-
* obj->update(i,val);
40-
* int param_2 = obj->sumRange(i,j);
41-
*/
106+
/*
107+
int main()
108+
{
109+
vector<int> nums = { 1,3,5 };
110+
NumArray* n = new NumArray(nums);
111+
cout << n->sumRange(0, 2) << endl; //9
112+
n->update(1, 2);
113+
cout << n->sumRange(0, 2) << endl; //8
114+
cout << n->sumRange(0, 1) << endl; //3
115+
cout << n->sumRange(0, 0) << endl; //1
116+
}
117+
*/

cpp/leetcode/309. best-time-to-buy-and-sell-stock-with-cooldown.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "public.h"
22

3-
//4ms, 93.19%
3+
//4ms, 87.41%
44
//DP problem
55
//三个状态: 最大收益: 买入/可买/冷却
66
//更新: 下一个买入=max(买入, 可买-价格), 下一个冷却=买入+价格, 下一个可买=max(可买, 冷却)

cpp/leetcode/310. minimum-height-trees.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "BinaryTree.h"
22

3-
//92ms, 97.39%
3+
//92ms, 84.24%
44
//初始化将叶节点(nodes[i].size()==1)记录下来,然后对于叶节点的下一个节点,判断其删除那个叶节点后是否是叶节点,是则记录下来
55
//直至当前只有1个或两个节点,他们就是root
66

@@ -32,11 +32,11 @@ class Solution {
3232
int temp = q.front();
3333
q.pop();
3434
n--;
35-
unordered_set<int>::iterator iter = nodes[temp].begin();
36-
nodes[*iter].erase(temp);
37-
if (nodes[*iter].size() == 1)
35+
int beginIndex = *nodes[temp].begin();
36+
nodes[beginIndex].erase(temp);
37+
if (nodes[beginIndex].size() == 1)
3838
{
39-
next.push(*iter);
39+
next.push(beginIndex);
4040
}
4141
}
4242
q = next;
@@ -45,7 +45,7 @@ class Solution {
4545
vector<int> res;
4646
while (!q.empty())
4747
{
48-
res.push_back(q.front());
48+
res.emplace_back(q.front());
4949
q.pop();
5050
}
5151
return res;

cpp/leetcode/312. burst-balloons.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "public.h"
22

3-
//20ms, 98.42%
3+
//16ms, 98.95%
44
//DP problem
55
//将nums两端扩展: 例如3 1 5 8 扩展为 1 3 1 5 8 1
66
//定义dp[i][j]表示戳破下标:[i,j]后的最大收益

cpp/leetcode/313. super-ugly-number.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "public.h"
22

3-
//76ms, 76.53%
3+
//64ms, 85.26%
44
//DP problem
55
//记录k个dp值, 表示下一个
66

@@ -9,12 +9,8 @@ class Solution {
99
int nthSuperUglyNumber(int n, vector<int>& primes) {
1010
int k = primes.size();
1111
vector<int> res(n, 0);
12-
//int *res = new int[n];
1312
res[0] = 1;
14-
vector<int> pos(k, 0);
15-
//int **pos = new int *[k];
16-
for (int i = 0; i < k; i++) //初始化k个下标
17-
pos[i] = 0;
13+
vector<int> pos(k, 0); //初始化k个下标成0
1814
int next = 1; //下一个存放位置
1915
while (next < n)
2016
{

0 commit comments

Comments
 (0)