3.29 二分查找
This commit is contained in:
parent
c85a5023f1
commit
a41a72c55b
47
src/main/java/binary_search/Search.java
Normal file
47
src/main/java/binary_search/Search.java
Normal file
@ -0,0 +1,47 @@
|
||||
package binary_search;
|
||||
/**
|
||||
* 题目: 33. 搜索旋转排序数组 (searchRange)
|
||||
* 描述:整数数组 nums 按升序排列,数组中的值 互不相同 。
|
||||
* 在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
|
||||
* 给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
|
||||
* 你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。
|
||||
|
||||
* 示例 1:
|
||||
输入:nums = [4,5,6,7,0,1,2], target = 0
|
||||
输出:4
|
||||
|
||||
* 链接:https://leetcode.cn/problems/search-in-rotated-sorted-array/
|
||||
*/
|
||||
//不会
|
||||
public class Search {
|
||||
public int search(int[] nums, int target) {
|
||||
int n = nums.length;
|
||||
if (n == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (n == 1) {
|
||||
return nums[0] == target ? 0 : -1;
|
||||
}
|
||||
int l = 0, r = n - 1;
|
||||
while (l <= r) {
|
||||
int mid = (l + r) / 2;
|
||||
if (nums[mid] == target) {
|
||||
return mid;
|
||||
}
|
||||
if (nums[0] <= nums[mid]) {
|
||||
if (nums[0] <= target && target < nums[mid]) {
|
||||
r = mid - 1;
|
||||
} else {
|
||||
l = mid + 1;
|
||||
}
|
||||
} else {
|
||||
if (nums[mid] < target && target <= nums[n - 1]) {
|
||||
l = mid + 1;
|
||||
} else {
|
||||
r = mid - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
48
src/main/java/binary_search/SearchInsert.java
Normal file
48
src/main/java/binary_search/SearchInsert.java
Normal file
@ -0,0 +1,48 @@
|
||||
package binary_search;
|
||||
/**
|
||||
* 题目: 35. 搜索插入位置 (floodFill)
|
||||
* 描述:给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
|
||||
* 请必须使用时间复杂度为 O(log n) 的算法。
|
||||
|
||||
*
|
||||
* 示例 1:
|
||||
输入: nums = [1,3,5,6], target = 5
|
||||
输出: 2
|
||||
|
||||
* 链接:https://leetcode.cn/problems/search-insert-position/
|
||||
*/
|
||||
//第一道二分法的题,不熟练
|
||||
public class SearchInsert {
|
||||
public int searchInsert(int[] nums, int target) {
|
||||
int left = 0, right = nums.length - 1;
|
||||
while (left <= right) {
|
||||
int mid = (right + left) / 2;
|
||||
if (nums[mid] == target) {
|
||||
return mid;
|
||||
} else if (nums[mid] < target) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
right = mid - 1;
|
||||
}
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
private int helper(int[] nums, int target, int left, int right) {
|
||||
if (left > right) {
|
||||
return left;
|
||||
}
|
||||
int mid = (right + left) / 2;
|
||||
if (nums[mid] == target) {
|
||||
return mid;
|
||||
} else if (nums[mid] < target) {
|
||||
return helper(nums, target, mid + 1, right);
|
||||
} else {
|
||||
return helper(nums, target, left, mid - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public int searchInsert1(int[] nums, int target) {
|
||||
return helper(nums, target, 0, nums.length - 1);
|
||||
}
|
||||
}
|
32
src/main/java/binary_search/SearchMatrix.java
Normal file
32
src/main/java/binary_search/SearchMatrix.java
Normal file
@ -0,0 +1,32 @@
|
||||
package binary_search;
|
||||
/**
|
||||
* 题目: 74. 搜索二维矩阵 (searchMatrix)
|
||||
* 描述:给你一个满足下述两条属性的 m x n 整数矩阵:
|
||||
*
|
||||
* 每行中的整数从左到右按非严格递增顺序排列。
|
||||
* 每行的第一个整数大于前一行的最后一个整数。
|
||||
* 给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false 。
|
||||
|
||||
*
|
||||
* 示例 1:
|
||||
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
|
||||
输出:true
|
||||
|
||||
* 链接:https://leetcode.cn/problems/search-a-2d-matrix/
|
||||
*/
|
||||
public class SearchMatrix {
|
||||
public boolean searchMatrix(int[][] matrix, int target) {
|
||||
int r=matrix.length;
|
||||
int c=matrix[0].length;
|
||||
int i=0,j=c-1;
|
||||
while (i<=r-1 && j>=0){
|
||||
if(target==matrix[i][j])
|
||||
return true;
|
||||
else if(target>matrix[i][j])
|
||||
i++;
|
||||
else
|
||||
j--;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
88
src/main/java/binary_search/SearchRange.java
Normal file
88
src/main/java/binary_search/SearchRange.java
Normal file
@ -0,0 +1,88 @@
|
||||
package binary_search;
|
||||
/**
|
||||
* 题目: 34. 在排序数组中查找元素的第一个和最后一个位置 (searchRange)
|
||||
* 描述:给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
|
||||
* 如果数组中不存在目标值 target,返回 [-1, -1]。
|
||||
* 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
|
||||
|
||||
* 示例 1:
|
||||
输入:nums = [5,7,7,8,8,10], target = 8
|
||||
输出:[3,4]
|
||||
|
||||
* 链接:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/
|
||||
*/
|
||||
public class SearchRange {
|
||||
//极端情况下不是O(log n)
|
||||
public int[] searchRange(int[] nums, int target) {
|
||||
int left=0,right=nums.length-1;
|
||||
int tpleft=-1,tpright=-1;
|
||||
while (left<=right){
|
||||
int mid=(left+right)/2;
|
||||
if(target==nums[mid]){
|
||||
tpleft=mid-1;
|
||||
tpright=mid+1;
|
||||
while (tpleft>=left) {
|
||||
if (target == nums[tpleft])
|
||||
tpleft--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
tpleft++;
|
||||
while (tpright<=right) {
|
||||
if (target == nums[tpright])
|
||||
tpright++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
tpright--;
|
||||
break;
|
||||
}
|
||||
else if(target>nums[mid])
|
||||
left=mid+1;
|
||||
else
|
||||
right=mid-1;
|
||||
}
|
||||
return new int[]{tpleft,tpright};
|
||||
}
|
||||
|
||||
private int findLeft(int[] nums, int target) {
|
||||
int left = 0, right = nums.length - 1;
|
||||
int index = -1;
|
||||
while (left <= right) {
|
||||
int mid = left + (right - left) / 2;
|
||||
if (nums[mid] >= target) {
|
||||
right = mid - 1;
|
||||
} else {
|
||||
left = mid + 1;
|
||||
}
|
||||
if (nums[mid] == target) {
|
||||
index = mid;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
// 找到目标值的最后一次出现位置
|
||||
private int findRight(int[] nums, int target) {
|
||||
int left = 0, right = nums.length - 1;
|
||||
int index = -1;
|
||||
while (left <= right) {
|
||||
int mid = left + (right - left) / 2;
|
||||
if (nums[mid] <= target) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
right = mid - 1;
|
||||
}
|
||||
if (nums[mid] == target) {
|
||||
index = mid;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public int[] searchRange1(int[] nums, int target) {
|
||||
int leftIndex = findLeft(nums, target);
|
||||
int rightIndex = findRight(nums, target);
|
||||
return new int[]{leftIndex, rightIndex};
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user