Skip to content

Commit f65144a

Browse files
author
anduo
committed
nine chapter ch02 binary search and sorted array
1 parent a1837cc commit f65144a

13 files changed

+558
-2
lines changed

readme.md

+34
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,38 @@ doc中有好几份文档,比较经典,可以参考。
187187
## chapter02 binary search & sorted array
188188
这一部分都可以使用bs模板来解决问题 [二分搜索模板](./src/template/bs_template.md)
189189

190+
算法面试中如果需要优化O(n)的时间复杂度,那么只能是O(logn)的二分法
191+
192+
**二分搜索四点要素**:
193+
1. start + 1 < end
194+
2. start + (end - start) / 2
195+
3. A[mid] ==, <, >
196+
4. A[start] A[end] ? target
197+
190198
- [question01:first position of target](./src/ninechapter/ch02_binary_search_and_sorted_array/Question01FirstPositionOfTarget.java) || [lintcode](http://www.lintcode.com/zh-cn/problem/first-position-of-target/)
199+
- [question02:search for a range](./src/ninechapter/ch02_binary_search_and_sorted_array/Question02SearchForARange.java)
200+
- [question03:search insert position](./src/ninechapter/ch02_binary_search_and_sorted_array/Question03SearchInsertPosition.java)
201+
- [question04:search a 2D matrix](./src/ninechapter/ch02_binary_search_and_sorted_array/Question04SearchA2DMatrix.java)
202+
- [question05:search a 2D matrix ii](./src/ninechapter/ch02_binary_search_and_sorted_array/Question05SearchA2DMatrixII.java)
203+
- [question06:first bad version](./src/ninechapter/ch02_binary_search_and_sorted_array/Question06FirstBadVersion.java)
204+
- [question07:find peak element](./src/ninechapter/ch02_binary_search_and_sorted_array/Question07FindPeakElement.java)
205+
- [question08:find minimum in rotated sorted array](./src/ninechapter/ch02_binary_search_and_sorted_array/Question08FindMinimumInRotatedSortedArray.java)
206+
- [question09:find minimum in rotated sorted array ii](./src/ninechapter/ch02_binary_search_and_sorted_array/Question08FindMinimumInRotatedSortedArrayII.java)
207+
- [question10:search in rotated sorted array](./src/ninechapter/ch02_binary_search_and_sorted_array/Question10SearchInRotatedSortedArray.java)
208+
- [question11:search in rotated sorted array ii](./src/ninechapter/ch02_binary_search_and_sorted_array/Question10SearchInRotatedSortedArrayII.java)
209+
- [question12:median of two sorted arrays](./src/ninechapter/ch02_binary_search_and_sorted_array/Question12MedianOfTwoSortedArrays.java)
210+
- [question13:recover rotated sorted array](./src/ninechapter/ch02_binary_search_and_sorted_array/Question13RecoverRotatedSortedArray.java)
211+
- [question14:rotate string](./src/ninechapter/ch02_binary_search_and_sorted_array/Question14RotateString.java)
212+
- [question15:reverse words in a string](./src/ninechapter/ch02_binary_search_and_sorted_array/Question15ReverseWordsInAString.java)
213+
214+
**总结**
215+
1. Binary Search Template (4 key points)
216+
2. Rotated Sorted Array
217+
1. Find Minimum
218+
2. Find Target
219+
3. why o(n) with duplicates ?
220+
3. Find Median in Two Sorted Array
221+
find kth
222+
4. Reverse in 3 steps
223+
224+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package ninechapter.ch02_binary_search_and_sorted_array;
2+
/**
3+
* 写出一个高效的算法来搜索 m × n矩阵中的值。
4+
* 这个矩阵具有以下特性:
5+
* 每行中的整数从左到右是排序的。
6+
* 每行的第一个数大于上一行的最后一个整数。
7+
* <p>
8+
* [
9+
* [1, 3, 5, 7],
10+
* [10, 11, 16, 20],
11+
* [23, 30, 34, 50]
12+
* ]
13+
* target = 3,返回 true
14+
*/
15+
16+
/**
17+
* Created by anduo on 17-3-13.
18+
*/
19+
public class Question04SearchA2DMatrix {
20+
public boolean searchMatrix(int[][] matrix, int target) {
21+
// 二分
22+
if (matrix == null
23+
|| matrix.length == 0
24+
|| matrix[0] == null
25+
|| matrix[0].length == 0) {
26+
return false;
27+
}
28+
29+
int rows = matrix.length;
30+
int cols = matrix[0].length;
31+
32+
int row;// 需要找的目标行
33+
// 先找到行
34+
int start = 0;
35+
int end = rows - 1;
36+
while (start + 1 < end) {
37+
int mid = start + (end - start) / 2;
38+
int v = matrix[mid][0];
39+
if (v == target) {
40+
return true;
41+
} else if (v > target) {// 说明一定在mid行的上班部分
42+
end = mid;
43+
} else {// 在mid行的下半部分
44+
start = mid;
45+
}
46+
}
47+
if (matrix[end][0] <= target) {// 如果在上半部分
48+
row = end;
49+
} else if (matrix[start][0] <= target) {
50+
row = start;
51+
} else {
52+
return false;
53+
}
54+
55+
// 找列
56+
start = 0;
57+
end = cols - 1;
58+
while (start + 1 < end) {
59+
int mid = start + (end - start) / 2;
60+
int v = matrix[row][mid];
61+
if (v == target) {
62+
return true;
63+
} else if (v > target) {// 说明一定在mid列的前半部分
64+
end = mid;
65+
} else {// 在mid列的后部分
66+
start = mid;
67+
}
68+
}
69+
if (matrix[row][start] == target) {
70+
return true;
71+
} else if (matrix[row][end] == target) {
72+
return true;
73+
}
74+
return false;
75+
}
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package ninechapter.ch02_binary_search_and_sorted_array;
2+
/**
3+
* 写出一个高效的算法来搜索m×n矩阵中的值,返回这个值出现的次数。
4+
* 这个矩阵具有以下特性:
5+
* 每行中的整数从左到右是排序的。
6+
* 每一列的整数从上到下是排序的。
7+
* 在每一行或每一列中没有重复的整数。
8+
* <p>
9+
* [
10+
* [1, 3, 5, 7],
11+
* [2, 4, 7, 8],
12+
* [3, 5, 9, 10]
13+
* ]
14+
* target = 3,返回 2
15+
*/
16+
17+
/**
18+
* Created by anduo on 17-3-13.
19+
*/
20+
public class Question05SearchA2DMatrixII {
21+
public int searchMatrix(int[][] matrix, int target) {
22+
if (matrix == null
23+
|| matrix.length == 0
24+
|| matrix[0] == null
25+
|| matrix[0].length == 0) {
26+
return 0;
27+
}
28+
29+
int rows = matrix.length;
30+
int cols = matrix[0].length;
31+
32+
int x = rows - 1;
33+
int y = 0;
34+
int count = 0;
35+
while (x >= 0 && y < cols) {
36+
if (matrix[x][y] == target) {// 如果找到相应的元素
37+
count++;
38+
x--;
39+
y++;
40+
// 行列都移动
41+
} else if (matrix[x][y] < target) {
42+
y++;// 在下一列
43+
} else {
44+
x--;//在上一行
45+
}
46+
}
47+
48+
return count;
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package ninechapter.ch02_binary_search_and_sorted_array;
2+
3+
/**
4+
* 代码库的版本号是从 1 到 n 的整数。
5+
* 某一天,有人提交了错误版本的代码,因此造成自身及之后版本的代码在单元测试中均出错。
6+
* 请找出第一个错误的版本号。
7+
* 你可以通过isBadVersion的接口来判断版本号version是否在单元测试中出错,
8+
* 具体接口详情和调用方法请见代码的注释部分。
9+
* 样例
10+
* 给出 n=5
11+
* 调用isBadVersion(3),得到false
12+
* 调用isBadVersion(5),得到true
13+
* 调用isBadVersion(4),得到true
14+
* 此时我们可以断定4是第一个错误的版本号
15+
* Created by anduo on 17-3-13.
16+
*/
17+
public class Question06FirstBadVersion {
18+
/**
19+
* @param n: An integers.
20+
* @return: An integer which is the first bad version.
21+
*/
22+
public int findFirstBadVersion(int n) {
23+
int start = 0;
24+
int end = n;
25+
while (start + 1 < end) {
26+
int mid = start + (end - start) / 2;
27+
if (SVNRepo.isBadVersion(mid)) {
28+
end = mid;
29+
} else {
30+
start = mid;
31+
}
32+
}
33+
if (SVNRepo.isBadVersion(start)) {
34+
return start;
35+
}
36+
return end;
37+
}
38+
39+
static class SVNRepo {
40+
public static boolean isBadVersion(int n) {
41+
return true;
42+
}
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package ninechapter.ch02_binary_search_and_sorted_array;
2+
3+
/**
4+
* 寻找峰值
5+
* http://www.lintcode.com/zh-cn/problem/find-peak-element/
6+
* 你给出一个整数数组(size为n),其具有以下特点:
7+
* 相邻位置的数字是不同的
8+
* A[0] < A[1] 并且 A[n - 2] > A[n - 1]
9+
* 假定P是峰值的位置则满足A[P] > A[P-1]且A[P] > A[P+1],返回数组中任意一个峰值的位置。
10+
* <p>
11+
* --------
12+
* 给出数组[1, 2, 1, 3, 4, 5, 7, 6]返回1, 即数值 2 所在位置, 或者6, 即数值 7 所在位置.
13+
* Created by anduo on 17-3-13.
14+
*/
15+
public class Question07FindPeakElement {
16+
/**
17+
* @param A: An integers array.
18+
* @return: return any of peek positions.
19+
*/
20+
public int findPeak(int[] A) {
21+
// 局部有序
22+
if (A == null || A.length == 0) {
23+
return -1;
24+
}
25+
26+
int start = 1;
27+
int end = A.length - 2;
28+
while (start + 1 < end) {
29+
int mid = start + (end - start) / 2;
30+
if (A[mid] < A[mid - 1]) {
31+
end = mid;
32+
} else if (A[mid] < A[mid + 1]) {
33+
start = mid;
34+
} else {
35+
end = mid;
36+
}
37+
}
38+
if (A[start] < A[end]) {
39+
return end;
40+
} else {
41+
return start;
42+
}
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package ninechapter.ch02_binary_search_and_sorted_array;
2+
3+
/**
4+
* http://www.lintcode.com/zh-cn/problem/find-minimum-in-rotated-sorted-array/
5+
* 假设一个旋转排序的数组其起始位置是未知的
6+
* (比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2)。
7+
* 你需要找到其中最小的元素。
8+
* 你可以假设数组中不存在重复的元素。
9+
* Created by anduo on 17-3-13.
10+
*/
11+
public class Question08FindMinimumInRotatedSortedArray {
12+
/**
13+
* @param nums: a rotated sorted array
14+
* @return: the minimum number in the array
15+
*/
16+
public int findMin(int[] nums) {
17+
if (nums == null || nums.length == 0) {
18+
return -1;
19+
}
20+
if (nums.length == 1) {
21+
return nums[0];
22+
}
23+
24+
25+
int start = 0, end = nums.length - 1;
26+
int target = nums[end];
27+
28+
// 4 5 6 7 0 1 2
29+
// find the first element <= target
30+
while (start + 1 < end) {
31+
int mid = start + (end - start) / 2;
32+
if (nums[mid] == target) {
33+
// if mid equals to end, that means it's fine to remove end
34+
// the smallest element won't be removed
35+
end--;
36+
} else if (nums[mid] <= target) {
37+
end = mid;
38+
} else {
39+
start = mid;
40+
}
41+
}
42+
if (nums[start] <= target) {
43+
return nums[start];
44+
} else {
45+
return nums[end];
46+
}
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package ninechapter.ch02_binary_search_and_sorted_array;
2+
3+
/**
4+
* http://www.lintcode.com/zh-cn/problem/find-minimum-in-rotated-sorted-array-ii/
5+
* 假设一个旋转排序的数组其起始位置是未知的
6+
* (比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2)。
7+
* 你需要找到其中最小的元素。
8+
* 数组中可能存在重复的元素。
9+
* Created by anduo on 17-3-13.
10+
*/
11+
public class Question09FindMinimumInRotatedSortedArrayII {
12+
/**
13+
* @param nums: a rotated sorted array
14+
* @return: the minimum number in the array
15+
*/
16+
public int findMin(int[] nums) {
17+
if (nums == null || nums.length == 0) {
18+
return -1;
19+
}
20+
if (nums.length == 1) {
21+
return nums[0];
22+
}
23+
if (nums.length == 2) {
24+
return Math.min(nums[0], nums[1]);
25+
}
26+
27+
int start = 0, end = nums.length - 1;
28+
int target = nums[nums.length - 1];
29+
30+
// 4 5 6 7 0 1 2
31+
// find the first element <= target
32+
while (start + 1 < end) {
33+
int mid = start + (end - start) / 2;
34+
if (nums[mid] <= target) {
35+
end = mid;
36+
} else {
37+
start = mid;
38+
}
39+
}
40+
if (nums[start] <= target) {
41+
return nums[start];
42+
} else {
43+
return nums[end];
44+
}
45+
}
46+
}

src/ninechapter/ch02_binary_search_and_sorted_array/Question04SearchInRotatedSortedArray.java src/ninechapter/ch02_binary_search_and_sorted_array/Question10SearchInRotatedSortedArray.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* 给定一个目标值进行搜索,如果在数组中找到目标值返回数组中的索引位置,否则返回-1。
99
* 你可以假设数组中不存在重复的元素。
1010
*/
11-
public class Question04SearchInRotatedSortedArray {
11+
public class Question10SearchInRotatedSortedArray {
1212
public int search(int[] A, int target) {
1313
if (A == null || A.length == 0) {
1414
return -1;

src/ninechapter/ch02_binary_search_and_sorted_array/Question05SearchInRotatedSortedII.java src/ninechapter/ch02_binary_search_and_sorted_array/Question11SearchInRotatedSortedArrayII.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* 为何会影响?
1111
* 写出一个函数判断给定的目标值是否出现在数组中。
1212
*/
13-
public class Question05SearchInRotatedSortedII {
13+
public class Question11SearchInRotatedSortedArrayII {
1414
// 这个问题在面试中不会让实现完整程序
1515
// 只需要举出能够最坏情况的数据是 [1,1,1,1... 1] 里有一个0即可。
1616
// 在这种情况下是无法使用二分法的,复杂度是O(n)

0 commit comments

Comments
 (0)