Skip to content

Commit 2850eca

Browse files
authored
Merge pull request #99 from KongJHong/master
Add Solution 123[CPP]
2 parents eb3c7a8 + 1c38ac7 commit 2850eca

File tree

9 files changed

+367
-1
lines changed

9 files changed

+367
-1
lines changed

solution/0012.Integer to Roman/Solution.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ class Solution {
66
public String intToRoman(int num) {
77
return M[num / 1000] + C[(num % 1000) / 100] + X[(num % 100) / 10] + I[num % 10];
88
}
9-
}
9+
}
10+

solution/0018.4Sum/Solution.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
class Solution {
2+
public:
3+
vector<vector<int>> fourSum(vector<int>& nums, int target) {
4+
int len = nums.size();
5+
vector<vector<int>> ans;
6+
if(len < 4)return ans;
7+
sort(nums.begin(),nums.end());
8+
9+
int left;
10+
int right;
11+
int sum;
12+
for(int i = 0;i<len;i++){
13+
if(i> 0 && nums[i] == nums[i-1])continue;
14+
for(int j = i + 1;j<len;j++){
15+
if(j > i+1 && nums[j] == nums[j-1])continue;
16+
17+
left = j+1;
18+
right = len - 1;
19+
20+
while(left < right){
21+
22+
sum = nums[i] + nums[j] + nums[left] + nums[right];
23+
24+
if(sum == target){
25+
vector<int> tmp{nums[i],nums[j],nums[left],nums[right]};
26+
ans.push_back(tmp);
27+
28+
while(left < right && nums[left] == nums[left+1])left++;
29+
while(left < right && nums[right] == nums[right-1])right--;
30+
left++;
31+
right--;
32+
}
33+
else if(sum < target)left++;
34+
else if(sum > target)right--;
35+
}
36+
}
37+
}
38+
return ans;
39+
}
40+
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
class Solution {
2+
public:
3+
void nextPermutation(vector<int> &nums) {
4+
int len = nums.size();
5+
6+
if (len == 0)return;
7+
int i,j;
8+
for(i = len - 2;i>=0;i--){
9+
if(nums[i+1] > nums[i]){
10+
for(j = len - 1;j>i;j--){
11+
if(nums[j]>nums[i])break;
12+
}
13+
swap(nums[i],nums[j]);
14+
reverse(nums.begin()+i+1,nums.end());
15+
return;
16+
}
17+
}
18+
reverse(nums.begin(),nums.end());
19+
}
20+
};
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
## 接雨水
2+
### 问题描述
3+
4+
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
5+
6+
![ ](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/10/22/rainwatertrap.png)
7+
8+
上面是由数组`[0,1,0,2,1,0,1,3,2,1,2,1]` 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。
9+
10+
示例:
11+
```
12+
输入: [0,1,0,2,1,0,1,3,2,1,2,1]
13+
输出: 6
14+
```
15+
16+
### 思路
17+
18+
方法是找凹槽,怎么找呢?
19+
20+
1. 设置`slow,fast`两个下标代表凹槽的左右边界,一旦遇到`height[fast]>=height[slow]`的情况,计算凹槽的容积
21+
2. 上面情况是以右边界高度一定大于左边界为准的,当形成凹槽且左边界大于右边界时,要怎么记录呢?答案是设置`stopPoint`点,规则是当`height[fast]>height[stopPoint]`时有`stopPoint = fast`记录右边最高点;同时当fast越界时,会到`stopPoint`
22+
23+
```CPP
24+
class Solution {
25+
public:
26+
int trap(vector<int>& height) {
27+
int len = height.size();
28+
if(len == 0 || len == 1)return 0;
29+
30+
int slow = 0;
31+
int fast = 1;
32+
33+
int stopPoint;
34+
35+
int total = 0;
36+
int bottom;
37+
int tmp = 0;
38+
while(fast < len){
39+
//每次更新stopPoint
40+
stopPoint = fast;
41+
while(fast < len && height[fast] <= height[slow]){
42+
if(height[fast] > height[stopPoint])
43+
stopPoint = fast;
44+
fast++;
45+
}
46+
47+
//越界了要回到stopPoint
48+
if(fast >= len)fast = stopPoint;
49+
50+
tmp = 0;
51+
bottom = min(height[slow],height[fast]);
52+
for(int i = slow+1;i<fast;i++){
53+
tmp += bottom - height[i];
54+
}
55+
slow = fast;
56+
total += tmp;
57+
fast++;
58+
}
59+
return total;
60+
}
61+
};
62+
```
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
class Solution {
2+
public:
3+
int trap(vector<int>& height) {
4+
int len = height.size();
5+
if(len == 0 || len == 1)return 0;
6+
7+
int slow = 0;
8+
int fast = 1;
9+
10+
int stopPoint;
11+
12+
int total = 0;
13+
int bottom;
14+
int tmp = 0;
15+
while(fast < len){
16+
//每次更新stopPoint
17+
stopPoint = fast;
18+
while(fast < len && height[fast] <= height[slow]){
19+
if(height[fast] > height[stopPoint])
20+
stopPoint = fast;
21+
fast++;
22+
}
23+
24+
//越界了要回到stopPoint
25+
if(fast >= len)fast = stopPoint;
26+
27+
tmp = 0;
28+
bottom = min(height[slow],height[fast]);
29+
for(int i = slow+1;i<fast;i++){
30+
tmp += bottom - height[i];
31+
}
32+
slow = fast;
33+
total += tmp;
34+
fast++;
35+
}
36+
return total;
37+
}
38+
};
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
## 买卖股票的最佳时机 III
2+
3+
### 问题描述
4+
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
5+
6+
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
7+
8+
注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
9+
10+
示例 1:
11+
```
12+
输入: [3,3,5,0,0,3,1,4]
13+
输出: 6
14+
解释: 在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。
15+
随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。
16+
```
17+
示例 2:
18+
```
19+
输入: [1,2,3,4,5]
20+
输出: 4
21+
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
22+
注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
23+
因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
24+
```
25+
示例 3:
26+
```
27+
输入: [7,6,4,3,1]
28+
输出: 0
29+
解释: 在这个情况下, 没有交易完成, 所以最大利润为 0。
30+
```
31+
-------------
32+
### 思路:
33+
34+
建立两个数组,因为是只能两次交易,所以有左右数组
35+
36+
- 一个数组是`left[i]`,表示在第i天及之前交易的最大利润
37+
- 一个数组是`right[i]`,表示在第i天及之后交易的最大利润
38+
39+
最后同时遍历,求和取出最大值就可以了
40+
41+
```CPP
42+
class Solution {
43+
public:
44+
int maxProfit(vector<int>& prices) {
45+
int left = 0;
46+
int len = prices.size();
47+
if(len == 0 || len == 1)return 0;
48+
49+
vector<int> leftArr(len, 0);
50+
vector<int> rightArr(len, 0);
51+
52+
int diff, day = 1, minPrice, maxPrice, maxProfit;
53+
54+
//计算某一天及之前的最大利益
55+
minPrice = prices[0];
56+
maxProfit = 0;
57+
for (day = 1; day < len; day++) {
58+
diff = prices[day] - minPrice;
59+
if (diff < 0)minPrice = prices[day];
60+
else if (diff > maxProfit)maxProfit = diff;
61+
62+
leftArr[day] = maxProfit;
63+
}
64+
65+
//计算某一天及之前的最大利益
66+
maxPrice = prices[len - 1];
67+
maxProfit = 0;
68+
for (day = len - 2; day >= 0; day--) {
69+
diff = maxPrice - prices[day];
70+
if (diff < 0)maxPrice = prices[day];
71+
else if (diff > maxProfit)maxProfit = diff;
72+
73+
rightArr[day] = maxProfit;
74+
}
75+
76+
int sum = 0;
77+
maxProfit = leftArr[0] + rightArr[0];
78+
for (int i = 1; i < len; i++) {
79+
sum = leftArr[i] + rightArr[i];
80+
if (sum > maxProfit)maxProfit = sum;
81+
}
82+
83+
return maxProfit;
84+
}
85+
};
86+
```
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
class Solution {
2+
public:
3+
int maxProfit(vector<int>& prices) {
4+
int left = 0;
5+
int len = prices.size();
6+
if(len == 0 || len == 1)return 0;
7+
8+
vector<int> leftArr(len, 0);
9+
vector<int> rightArr(len, 0);
10+
11+
int diff, day = 1, minPrice, maxPrice, maxProfit;
12+
13+
//计算某一天及之前的最大利益
14+
minPrice = prices[0];
15+
maxProfit = 0;
16+
for (day = 1; day < len; day++) {
17+
diff = prices[day] - minPrice;
18+
if (diff < 0)minPrice = prices[day];
19+
else if (diff > maxProfit)maxProfit = diff;
20+
21+
leftArr[day] = maxProfit;
22+
}
23+
24+
//计算某一天及之前的最大利益
25+
maxPrice = prices[len - 1];
26+
maxProfit = 0;
27+
for (day = len - 2; day >= 0; day--) {
28+
diff = maxPrice - prices[day];
29+
if (diff < 0)maxPrice = prices[day];
30+
else if (diff > maxProfit)maxProfit = diff;
31+
32+
rightArr[day] = maxProfit;
33+
}
34+
35+
int sum = 0;
36+
maxProfit = leftArr[0] + rightArr[0];
37+
for (int i = 1; i < len; i++) {
38+
sum = leftArr[i] + rightArr[i];
39+
if (sum > maxProfit)maxProfit = sum;
40+
}
41+
42+
return maxProfit;
43+
}
44+
};
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
## 找到所有数组中消失的数字
2+
3+
### 问题描述
4+
5+
给定一个范围在 `1 ≤ a[i] ≤ n ( n = 数组大小 )` 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。
6+
7+
找到所有在 [1, n] 范围之间没有出现在数组中的数字。
8+
9+
您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。
10+
11+
**示例:**
12+
```
13+
输入:
14+
[4,3,2,7,8,2,3,1]
15+
16+
输出:
17+
[5,6]
18+
```
19+
20+
### 解法
21+
22+
题目要求不使用额外空间,所以计数排序的方法不可取;
23+
24+
根据题目的条件,给定的`a[i]`是在`[1,n]`的范围内,所以可以利用这种关系来对数组进行处理,如`a[a[i]] = -a[a[i]`作反标记,最终若`a[i]>0`的话,则证明该下标`i`没有出现过,加入输出数组
25+
26+
```CPP
27+
class Solution {
28+
public:
29+
vector<int> findDisappearedNumbers(vector<int>& nums) {
30+
int len = nums.size();
31+
vector<int> ans;
32+
if(len == 0)return ans;
33+
34+
int index;
35+
for(int i = 0;i<len;++i){
36+
index = abs(nums[i]) - 1;
37+
38+
if(nums[index] > 0)
39+
nums[index] = -nums[index];
40+
}
41+
42+
43+
for(int i = 0;i<len;++i){
44+
if(nums[i] > 0)
45+
ans.push_back(i+1);
46+
}
47+
48+
return ans;
49+
}
50+
};
51+
```
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Solution {
2+
public:
3+
vector<int> findDisappearedNumbers(vector<int>& nums) {
4+
int len = nums.size();
5+
vector<int> ans;
6+
if(len == 0)return ans;
7+
8+
int index;
9+
for(int i = 0;i<len;++i){
10+
index = abs(nums[i]) - 1;
11+
12+
if(nums[index] > 0)
13+
nums[index] = -nums[index];
14+
}
15+
16+
17+
for(int i = 0;i<len;++i){
18+
if(nums[i] > 0)
19+
ans.push_back(i+1);
20+
}
21+
22+
return ans;
23+
}
24+
};

0 commit comments

Comments
 (0)