457 经典二分查找问题
https://www.lintcode.com/problem/457
- 模板一
public class Solution {
public int findPosition(int[] nums, int target) {
if (nums == null || nums.length == 0) return -1;
//输入:nums = [1,2,2,4,5,5], target = 2
//nums[1...2]这个区间的数字都等于target
int l = 0, r = nums.length - 1;
while (l < r) { //当循环结束时,l == r
int mid = l + r + 1 >> 1;
if (nums[mid] <= target) l = mid; //用变量l从左向右寻找target,找到的是最右边的下标2
else r = mid - 1;
}
if (nums[l] == target) return l;
else return -1;
}
}
public class Solution {
public int findPosition(int[] nums, int target) {
if (nums == null || nums.length == 0) return -1;
//输入:nums = [1,2,2,4,5,5], target = 2
//nums[1...2]这个区间的数字都等于target
int l = 0, r = nums.length - 1;
while (l < r) { //当循环结束时,l == r
int mid = l + r >> 1;
if (nums[mid] >= target) r = mid; //用变量r从右向左寻找target,找到的是最左边的下标1
else l = mid + 1;
}
if (nums[r] == target) return r;
else return -1;
}
}
- 模板二
public class Solution {
public int findPosition(int[] nums, int target) {
if (nums == null || nums.length == 0) return -1;
//输入:nums = [1,2,2,4,5,5], target = 2
//nums[1...2]这个区间的数字都等于target
int l = 0, r = nums.length - 1, ans = 0;
while (l <= r) { //当循环结束时,l == r + 1
int mid = l + r >> 1;
if (nums[mid] <= target) {ans = mid; l = mid + 1;} //用变量ans从左向右寻找target,找到的是最右边的下标2
else r = mid - 1;
}
if (nums[ans] == target) return ans;
else return -1;
}
}
public class Solution {
public int findPosition(int[] nums, int target) {
if (nums == null || nums.length == 0) return -1;
//输入:nums = [1,2,2,4,5,5], target = 2
//nums[1...2]这个区间的数字都等于target
int l = 0, r = nums.length - 1, ans = 0;
while (l <= r) { //当循环结束时,l == r + 1
int mid = l + r >> 1;
if (nums[mid] >= target) {ans = mid; r = mid - 1;} //用变量ans从右向左寻找target,找到的是最左边的下标1
else l = mid + 1;
}
if (nums[ans] == target) return ans;
else return -1;
}
}
- 模板三
public class Solution {
public int findPosition(int[] nums, int target) {
if (nums == null || nums.length == 0) return -1;
//输入:nums = [1,2,2,4,5,5], target = 2
//nums[1...2]这个区间的数字都等于target
int l = 0, r = nums.length; //左闭右开[l, r)
while (l + 1 < r) { //当循环结束时,l + 1 == r
int mid = l + r >> 1;
if (nums[mid] <= target) l = mid; //用变量l从左向右寻找target,找到的是最右边的下标2
else r = mid;
}
if (nums[l] == target) return l;
else return -1;
}
}
public class Solution {
public int findPosition(int[] nums, int target) {
if (nums == null || nums.length == 0) return -1;
//输入:nums = [1,2,2,4,5,5], target = 2
//nums[1...2]这个区间的数字都等于target
int l = -1, r = nums.length - 1; //左开右闭(l, r]
while (l + 1 < r) { //当循环结束时,l + 1 == r
int mid = l + r >> 1;
if (nums[mid] >= target) r = mid; //用变量r从右向左寻找target,找到的是最左边的下标1
else l = mid;
}
if (nums[r] == target) return r;
else return -1;
}
}
- 模板四(无逻辑可言)
public class Solution {
public int findPosition(int[] nums, int target) {
if (nums == null || nums.length == 0) return -1;
//输入:nums = [1,2,2,4,5,5], target = 2
//nums[1...2]这个区间的数字都等于target
int l = 0, r = nums.length - 1;
while (l + 1 < r) {
int mid = l + r >> 1;
if (nums[mid] == target) r = mid;
else if (nums[mid] < target) l = mid + 1;
else r = mid - 1;
}
//循环结束时l = 0, r = 1
if (nums[l] == target) return l;
if (nums[r] == target) return r;
else return -1;
}
}
447 在大数组中查找
public class Solution {
public int searchBigSortedArray(ArrayReader reader, int target) {
int k = 1;
while (reader.get(k - 1) < target) k *= 2;
int l = 0, r = k - 1;
while (l < r) {
int mid = l + r >> 1;
if (reader.get(mid) >= target) r = mid;
else l = mid + 1;
}
if (reader.get(r) == target) return r;
else return -1;
}
}
460 在排序数组中找最接近的K个数
public class Solution {
public int[] kClosestNumbers(int[] A, int target, int k) {
int res[] = new int[k];
int l = 0, r = A.length - 1, ans = -1;
//目标是寻找 < target的数中最右边一个
//也就是寻找 <= target - 1的数中最右边一个
while (l <= r) {
int mid = l + r >> 1;
if (A[mid] <= target - 1) {ans = mid; l = mid + 1;}
else r = mid - 1;
}
int i = ans, j = ans + 1; //A[i] < target <= A[j]
for (int t = 0; t < k; t ++) {
if (i == -1) res[t] = A[j ++];
else if (j == A.length) res[t] = A[i --];
else if (target - A[i] <= A[j] - target) res[t] = A[i --];
else res[t] = A[j ++];
}
return res;
}
}
585 山脉序列中的最大值
public class Solution {
//并不需要特殊考虑讲义里说的,只有两个数的情况
public int mountainSequence(int[] nums) {
if (nums == null || nums.length == 0) return -1;
int l = 0, r = nums.length - 1;
while (l < r) {
int mid = l + r >> 1;
//从右往左,找满足(nums[mid] > nums[mid + 1])条件的最左边的数
if (nums[mid] > nums[mid + 1]) r = mid;
else l = mid + 1;
}
return nums[l];
}
}
public class Solution {
public int mountainSequence(int[] nums) {
if (nums == null || nums.length == 0) return -1;
int l = 0, r = nums.length - 1;
while (l < r) {
if (l + 1 == r) return Math.max(nums[l], nums[r]);
int mid = l + r >> 1;
if (nums[mid] > nums[mid - 1] && nums[mid] > nums[mid + 1]) return nums[mid];
else if (nums[mid] > nums[mid - 1] && nums[mid] < nums[mid + 1]) l = mid + 1;
else r = mid - 1;
}
return nums[l];
}
}
159 寻找旋转排序数组中的最小值
public class Solution {
public int findMin(int[] nums) {
if (nums == null || nums.length == 0) return -1;
int l = 0, r = nums.length - 1, target = nums[r];
while (l < r) {
int mid = l + r >> 1;
//从右往左,找满足(nums[mid] < target)条件的最左边的数
if (nums[mid] < target) r = mid;
else l = mid + 1;
}
return nums[l];
}
}
62 搜索旋转排序数组
public class Solution {
public int search(int[] A, int target) {
if (A == null || A.length == 0) return -1;
int l = 0, r = A.length - 1, left = A[l], right = A[r];
while (l < r) {
int mid = l + r >> 1;
if (A[mid] > right) {
if (left <= target && target <= A[mid]) r = mid;
else l = mid + 1;
}
else {
if (A[mid] < target && target <= right) l = mid + 1;
else r = mid;
}
}
if (A[l] == target) return l;
else return -1;
}
}
75 寻找峰值
public class Solution {
public int findPeak(int[] A) {
int l = 0, r = A.length - 1;
while (l < r) {
int mid = l + r >> 1;
if (A[mid] < A[mid - 1]) r = mid; //如果满足条件,则左侧一定有山峰
else l = mid + 1;
}
return r - 1;
}
}
183 · 木材加工
public class Solution {
public int count(int[] L, int x) {
int res = 0;
for (int i = 0; i < L.length; i ++) res += L[i] / x;
return res;
}
public int woodCut(int[] L, int k) {
int l = 1, r = 0;
for (int i = 0; i < L.length; i ++) r = Math.max(r, L[i]);
while (l < r) {
int mid = l + (r - l + 1 >> 1);
if (count(L, mid) >= k) l = mid;
else r = mid - 1;
}
if (count(L, l) < k) return 0;
else return l;
}
}