diff --git a/src/main/java/binary_search/Search.java b/src/main/java/binary_search/Search.java new file mode 100644 index 0000000..cbe4253 --- /dev/null +++ b/src/main/java/binary_search/Search.java @@ -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; + } +} diff --git a/src/main/java/binary_search/SearchInsert.java b/src/main/java/binary_search/SearchInsert.java new file mode 100644 index 0000000..332ce54 --- /dev/null +++ b/src/main/java/binary_search/SearchInsert.java @@ -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); + } +} diff --git a/src/main/java/binary_search/SearchMatrix.java b/src/main/java/binary_search/SearchMatrix.java new file mode 100644 index 0000000..feb5054 --- /dev/null +++ b/src/main/java/binary_search/SearchMatrix.java @@ -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; + } +} diff --git a/src/main/java/binary_search/SearchRange.java b/src/main/java/binary_search/SearchRange.java new file mode 100644 index 0000000..6d6af24 --- /dev/null +++ b/src/main/java/binary_search/SearchRange.java @@ -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}; + } +}