Skip to content

Commit 5af68cb

Browse files
authored
Merge pull request #65 from KongJHong/master
Create Solution 048[CPP]
2 parents 9088b1a + 9966120 commit 5af68cb

File tree

8 files changed

+349
-0
lines changed

8 files changed

+349
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
## 组合总和2
2+
3+
### 题目描述
4+
5+
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
6+
7+
candidates 中的每个数字在每个组合中只能使用一次。
8+
9+
说明:
10+
11+
所有数字(包括目标数)都是正整数。
12+
解集不能包含重复的组合。
13+
14+
```
15+
示例 1:
16+
输入: candidates = [10,1,2,7,6,1,5], target = 8,
17+
所求解集为:
18+
[
19+
[1, 7],
20+
[1, 2, 5],
21+
[2, 6],
22+
[1, 1, 6]
23+
]
24+
25+
示例 2:
26+
输入: candidates = [2,5,2,1,2], target = 5,
27+
所求解集为:
28+
[
29+
[1,2,2],
30+
[5]
31+
]
32+
```
33+
34+
### 思路
35+
36+
和39题一模一样,注意他有重复数,需要去除重复的结果.
37+
38+
还要注意回溯是往后回溯,不是原地回溯了
39+
40+
```CPP
41+
class Solution {
42+
public:
43+
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
44+
vector<vector<int>> ans;
45+
vector<int> tmp;
46+
sort(candidates.begin(),candidates.end());
47+
int len = candidates.size();
48+
49+
dfs(ans,tmp,candidates,target,len,0);
50+
51+
return ans;
52+
}
53+
54+
void dfs(vector<vector<int>> &ans,vector<int> &tmp,vector<int> &nums,int target,int len,int index) {
55+
56+
if(target == 0){
57+
auto iter = find(ans.begin(),ans.end(),tmp);
58+
if(iter == ans.end())ans.push_back(tmp);
59+
}
60+
61+
for(int i = index;i<len && target >= nums[i];i++){
62+
tmp.push_back(nums[i]);
63+
dfs(ans,tmp,nums,target - nums[i],len,i+1);//注意i+1
64+
tmp.pop_back();
65+
}
66+
}
67+
};
68+
```
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Solution {
2+
public:
3+
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
4+
vector<vector<int>> ans;
5+
vector<int> tmp;
6+
sort(candidates.begin(),candidates.end());
7+
int len = candidates.size();
8+
9+
dfs(ans,tmp,candidates,target,len,0);
10+
11+
return ans;
12+
}
13+
14+
void dfs(vector<vector<int>> &ans,vector<int> &tmp,vector<int> &nums,int target,int len,int index) {
15+
16+
if(target == 0){
17+
auto iter = find(ans.begin(),ans.end(),tmp);
18+
if(iter == ans.end())ans.push_back(tmp);
19+
}
20+
21+
for(int i = index;i<len && target >= nums[i];i++){
22+
tmp.push_back(nums[i]);
23+
dfs(ans,tmp,nums,target - nums[i],len,i+1);//注意i+1
24+
tmp.pop_back();
25+
}
26+
}
27+
};
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
## 缺失的第一个正数
2+
3+
### 问题描述
4+
5+
给定一个未排序的整数数组,找出其中没有出现的最小的正整数。
6+
7+
```
8+
示例 1:
9+
输入: [1,2,0]
10+
输出: 3
11+
12+
示例 2:
13+
输入: [3,4,-1,1]
14+
输出: 2
15+
16+
示例 3:
17+
输入: [7,8,9,11,12]
18+
输出: 1
19+
```
20+
说明:
21+
你的算法的时间复杂度应为O(n),并且只能使用常数级别的空间。
22+
23+
### 思路
24+
25+
题目的描述一看有点不好理解,其实是把它们排序后,[-1,1,2,4,4,5,6]这里面缺的第一个正整数是3,0不算正整数
26+
27+
1. 对数组排序
28+
2. 过滤小于等于0的部分
29+
3. 从1开始比较,注意过滤重复的元素
30+
31+
```CPP
32+
class Solution {
33+
public:
34+
int firstMissingPositive(vector<int>& nums) {
35+
sort(nums.begin(),nums.end());
36+
int len = nums.size();
37+
if(len == 0)return 1;
38+
int i = 0;
39+
while(nums[i] <= 0 && i < len)i++;
40+
if(i == len)return 1;
41+
42+
int tmp = 1;
43+
while(i<len){
44+
if(nums[i] != tmp)return tmp;
45+
while(len>i+1 && nums[i] == nums[i+1])i++;//去重
46+
i++;
47+
tmp++;
48+
}
49+
return tmp;
50+
}
51+
};
52+
```
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
class Solution {
2+
public:
3+
int firstMissingPositive(vector<int>& nums) {
4+
sort(nums.begin(),nums.end());
5+
int len = nums.size();
6+
if(len == 0)return 1;
7+
int i = 0;
8+
while(nums[i] <= 0 && i < len)i++;
9+
if(i == len)return 1;
10+
11+
int tmp = 1;
12+
while(i<len){
13+
if(nums[i] != tmp)return tmp;
14+
while(len>i+1 && nums[i] == nums[i+1])i++;//去重
15+
i++;
16+
tmp++;
17+
}
18+
return tmp;
19+
}
20+
};

solution/048.Rotate Image/README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
## 48旋转图像
2+
3+
### 问题描述
4+
给定一个 n × n 的二维矩阵表示一个图像。
5+
6+
将图像顺时针旋转 90 度。
7+
8+
说明:
9+
10+
你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。
11+
```
12+
示例 1:
13+
给定 matrix =
14+
[
15+
[1,2,3],
16+
[4,5,6],
17+
[7,8,9]
18+
],
19+
20+
原地旋转输入矩阵,使其变为:
21+
[
22+
[7,4,1],
23+
[8,5,2],
24+
[9,6,3]
25+
]
26+
27+
示例 2:
28+
给定 matrix =
29+
[
30+
[ 5, 1, 9,11],
31+
[ 2, 4, 8,10],
32+
[13, 3, 6, 7],
33+
[15,14,12,16]
34+
],
35+
36+
原地旋转输入矩阵,使其变为:
37+
[
38+
[15,13, 2, 5],
39+
[14, 3, 4, 1],
40+
[12, 6, 8, 9],
41+
[16, 7,10,11]
42+
]
43+
```
44+
45+
### 思路:
46+
47+
本来以为是矩阵坐标表换的一种,用初等行变换做,但是这里和矩阵坐标没任何关系,而是整个矩阵旋转,所以老实找规律
48+
49+
```
50+
1 2 3 顺90° 7 4 1
51+
4 5 6 ========> 8 5 2
52+
7 8 9 9 6 3
53+
54+
等价于
55+
56+
1 2 3 转置 1 4 7 左右互换 7 4 1
57+
4 5 6 ========> 2 5 8 ===========> 8 5 2
58+
7 8 9 3 6 9 9 6 3
59+
60+
先当做是一种规律,数学证明以后补
61+
```
62+
63+
1. 先将矩阵转置
64+
2. 左右各列对称互换
65+
66+
```CPP
67+
class Solution {
68+
public:
69+
void rotate(vector<vector<int>>& matrix) {
70+
71+
int n = matrix.size();
72+
if(n <= 1)return ;
73+
74+
//先做转置
75+
for(int i = 0 ; i < n ; i++){
76+
for(int j = i;j < n ;j++){
77+
swap(matrix[i][j],matrix[j][i]);
78+
}
79+
}
80+
81+
//再做水平互换
82+
for(int i = 0 ; i < n ; i++){
83+
for(int j = 0;j < n/2;j++){
84+
swap(matrix[i][j],matrix[i][n-1-j]);
85+
}
86+
}
87+
}
88+
};
89+
```
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class Solution {
2+
public:
3+
void rotate(vector<vector<int>>& matrix) {
4+
5+
int n = matrix.size();
6+
if(n <= 1)return ;
7+
8+
//先做转置
9+
for(int i = 0 ; i < n ; i++){
10+
for(int j = i;j < n ;j++){
11+
swap(matrix[i][j],matrix[j][i]);
12+
}
13+
}
14+
15+
//再做水平互换
16+
for(int i = 0 ; i < n ; i++){
17+
for(int j = 0;j < n/2;j++){
18+
swap(matrix[i][j],matrix[i][n-1-j]);
19+
}
20+
}
21+
}
22+
};

solution/112.Path Sum/README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
## 路径总和
2+
3+
### 问题描述
4+
5+
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
6+
7+
说明: 叶子节点是指没有子节点的节点。
8+
9+
示例:
10+
给定如下二叉树,以及目标和 sum = 22,
11+
```
12+
5
13+
/ \
14+
4 8
15+
/ / \
16+
11 13 4
17+
/ \ \
18+
7 2 1
19+
```
20+
返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。
21+
22+
23+
### 思路
24+
25+
题目要求有没有路径到**叶子节点**使和等于目标值
26+
27+
主要考察对叶子节点是否判断准确
28+
29+
这道题很简单,但是准确率不高,原因是的判断条件不明确,左空右不空返回什么什么,右空左不空返回什么什么,调试一直错
30+
31+
叶子节点唯一判断就是左右空
32+
33+
`root->left == NULL && root->right==NULL`
34+
35+
```CPP
36+
/**
37+
* Definition for a binary tree node.
38+
* struct TreeNode {
39+
* int val;
40+
* TreeNode *left;
41+
* TreeNode *right;
42+
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
43+
* };
44+
*/
45+
class Solution {
46+
public:
47+
bool hasPathSum(TreeNode* root, int sum) {
48+
49+
if(root == NULL)return false;
50+
if(root->right == NULL && root->left == NULL && sum == root->val)return true;
51+
52+
bool leftTrue = hasPathSum(root->left,sum - root->val);
53+
bool rightTrue = hasPathSum(root->right,sum - root->val);
54+
55+
return (leftTrue || rightTrue);
56+
}
57+
};
58+
```

solution/112.Path Sum/Solution.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Solution {
2+
public:
3+
bool hasPathSum(TreeNode* root, int sum) {
4+
5+
if(root == NULL)return false;
6+
if(root->right == NULL && root->left == NULL && sum == root->val)return true;
7+
8+
bool leftTrue = hasPathSum(root->left,sum - root->val);
9+
bool rightTrue = hasPathSum(root->right,sum - root->val);
10+
11+
return (leftTrue || rightTrue);
12+
}
13+
};

0 commit comments

Comments
 (0)