Skip to content

Commit ac20cda

Browse files
authored
Merge pull request apachecn#150 from xshahq/master
第四题增加一个思路和第329题
2 parents ef5d838 + 392f0c2 commit ac20cda

File tree

2 files changed

+145
-11
lines changed

2 files changed

+145
-11
lines changed

docs/Leetcode_Solutions/C++/004. _Median_of_Two_Sorted_Arrays.md

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# 004. Median of Two Sorted Arrays
22

3-
**<font color=red>难度Hard<font>**
3+
**<font color=red>难度Hard<font>**
44

5-
## 刷题内容
6-
> 原题连接
5+
## 刷题内容
6+
> 原题连接
77
88
* https://leetcode.com/problems/median-of-two-sorted-arrays/submissions/
99

10-
> 内容描述
10+
> 内容描述
1111
1212
```
1313
There are two sorted arrays nums1 and nums2 of size m and n respectively.
@@ -30,10 +30,10 @@ nums2 = [3, 4]
3030
The median is (2 + 3)/2 = 2.5
3131
```
3232

33-
> 思路1
34-
******- 时间复杂度: O(n + m)*****- 空间复杂度: O(1)******
33+
> 思路1
34+
******- 时间复杂度: O(n + m)******- 空间复杂度: O(1)******
3535

36-
直接用暴利搜索,类似与归并两个有序的数组。遍历两个数组,当总长度等于(m+n)/ 2,注意区分总长度奇数和偶数
36+
直接用暴利搜索,类似与归并两个有序的数组。遍历两个数组,当总长度等于(m+n)/ 2,注意区分总长度奇数和偶数
3737
```cpp
3838
class Solution {
3939
public:
@@ -72,10 +72,10 @@ public:
7272
}
7373
};
7474
```
75-
> 思路2
76-
******- 时间复杂度: O(lg(min(n.m)))*****- 空间复杂度: O(1)******
75+
> 思路2
76+
******- 时间复杂度: O(lg(min(n.m)))******- 空间复杂度: O(1)******
7777
78-
我们可以通过二分查找优化算法,利用中位数的定义,将两个数组划分为左右两个部分,nums1左半部分加nums2左半部分等于nums1右半部分加nums2的右半部分,如果总长度为偶数,那么nums1左半部分加nums2左半部分等于nums1右半部分加nums2的右半部分加1。并且```max(nums1[i],nums2[j]) <= max(nums1[i + 1],nums2[j + 1])```,接下来我们只要二分查找找i,并且要注意边界情况
78+
我们可以通过二分查找优化算法,利用中位数的定义,将两个数组划分为左右两个部分,nums1左半部分加nums2左半部分等于nums1右半部分加nums2的右半部分,如果总长度为偶数,那么nums1左半部分加nums2左半部分等于nums1右半部分加nums2的右半部分加1。并且```max(nums1[i],nums2[j]) <= max(nums1[i + 1],nums2[j + 1])```,接下来我们只要二分查找找i,并且要注意边界情况
7979
8080
```cpp
8181
class Solution {
@@ -122,4 +122,38 @@ public:
122122
return sum % 2 ? min1 : (min1 + max1) / 2.0;
123123
}
124124
};
125-
```
125+
```
126+
> 思路3
127+
******- 时间复杂度: O(lg(n+m))******- 空间复杂度: O(1)******
128+
129+
由于题目中建议我们在时间复杂度O(lg(m+n))中完成,我们可以把这题看成寻找第k大的值,这样我们可以递归的去做,每次查找k/2,知道k等于1,注意边界值的处理
130+
```cpp
131+
class Solution {
132+
public:
133+
int getKth(vector<int> nums1, int start1, int end1, vector<int> nums2, int start2, int end2, int k) {
134+
int len1 = end1 - start1 + 1;
135+
int len2 = end2 - start2 + 1;
136+
if (len1 > len2) return getKth(nums2, start2, end2, nums1, start1, end1, k);
137+
if (len1 == 0) return nums2[start2 + k - 1];
138+
139+
if (k == 1) return min(nums1[start1], nums2[start2]);
140+
141+
int i = start1 + min(len1, k / 2) - 1;
142+
int j = start2 + min(len2, k / 2) - 1;
143+
144+
if (nums1[i] > nums2[j]) {
145+
return getKth(nums1, start1, end1, nums2, j + 1, end2, k - (j - start2 + 1));
146+
}
147+
else {
148+
return getKth(nums1, i + 1, end1, nums2, start2, end2, k - (i - start1 + 1));
149+
}
150+
}
151+
double findMedianSortedArrays(vector<int> nums1, vector<int> nums2) {
152+
int n = nums1.size();
153+
int m = nums2.size();
154+
int left = (n + m + 1) / 2;
155+
int right = (n + m + 2) / 2;
156+
return (getKth(nums1, 0, n - 1, nums2, 0, m - 1, left) + getKth(nums1, 0, n - 1, nums2, 0, m - 1, right)) * 0.5;
157+
}
158+
};
159+
```
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# 329. Longest Increasing Path in a Matrix
2+
3+
**<font color=red>难度Hard<font>**
4+
5+
## 刷题内容
6+
> 原题连接
7+
8+
* https://leetcode.com/problems/longest-increasing-path-in-a-matrix/
9+
10+
> 内容描述
11+
12+
```
13+
Given an integer matrix, find the length of the longest increasing path.
14+
15+
From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed).
16+
17+
Example 1:
18+
19+
Input: nums =
20+
[
21+
[9,9,4],
22+
[6,6,8],
23+
[2,1,1]
24+
]
25+
Output: 4
26+
Explanation: The longest increasing path is [1, 2, 6, 9].
27+
Example 2:
28+
29+
Input: nums =
30+
[
31+
[3,4,5],
32+
[3,2,6],
33+
[2,2,1]
34+
]
35+
Output: 4
36+
Explanation: The longest increasing path is [3, 4, 5, 6]. Moving diagonally is not allowed.
37+
```
38+
39+
> 思路
40+
******- 时间复杂度: O(n * m)******-空间复杂度: O(n * m)******
41+
42+
如果直接用DFS去做,时间复杂度为O(n^4),我们就需要对算法进行优化,定义一个二维数组用记忆化的方法去记录进行剪枝
43+
```cpp
44+
class Solution {
45+
public:
46+
int** dp;
47+
int len1,len2,ans;
48+
int dfs(vector<vector<int> >&matrix,int i,int j)
49+
{
50+
if(dp[i][j] != -1)
51+
return dp[i][j];
52+
//cout << i << j << endl;
53+
if(i && matrix[i][j] < matrix[i - 1][j])
54+
dp[i][j] = max(dp[i][j],dfs(matrix,i - 1,j) + 1);
55+
if(j < len2 - 1 && matrix[i][j] < matrix[i][j + 1])
56+
dp[i][j] = max(dp[i][j],dfs(matrix,i,j + 1) + 1);
57+
if(i < len1 - 1 && matrix[i][j] < matrix[i + 1][j])
58+
dp[i][j] = max(dp[i][j],dfs(matrix,i + 1,j) + 1);
59+
if(j && matrix[i][j] < matrix[i][j - 1])
60+
dp[i][j] = max(dp[i][j],dfs(matrix,i,j - 1) + 1);
61+
//cout << dp[i][j];
62+
if(dp[i][j] == -1)
63+
dp[i][j] = 1;
64+
ans = max(ans,dp[i][j]);
65+
return dp[i][j];
66+
}
67+
int longestIncreasingPath(vector<vector<int>>& matrix) {
68+
len1 = matrix.size();
69+
if(!len1)
70+
return 0;
71+
len2 = matrix[0].size();
72+
ans = 0;
73+
dp = new int*[len1];
74+
for(int i = 0; i < len1; ++i){
75+
dp[i] = new int[len2];
76+
for(int j=0;j<len2;j++)
77+
dp[i][j]= -1;
78+
}
79+
//cout << 1;
80+
for(int i = 0;i < matrix.size();++i)
81+
for(int j = 0;j < matrix[i].size();++j)
82+
if(dp[i][j] == -1)
83+
{
84+
//cout << 1;
85+
dfs(matrix,i,j);
86+
}
87+
reverse(matrix.begin(),matrix.end());
88+
for(int i = 0;i < matrix.size();++i)
89+
reverse(matrix[i].begin(),matrix[i].end());
90+
for(int i = 0;i < len1;++i)
91+
for(int j = 0;j < len2;++j)
92+
dp[i][j] = -1;
93+
for(int i = 0;i < matrix.size();++i)
94+
for(int j = 0;j < matrix[i].size();++j)
95+
if(dp[i][j] == -1)
96+
dfs(matrix,i,j);
97+
return ans;
98+
}
99+
};
100+
```

0 commit comments

Comments
 (0)