diff --git a/animation-simulation/二分查找及其变种/leetcode 81不完全有序查找目标元素(包含重复值) .md b/animation-simulation/二分查找及其变种/leetcode 81不完全有序查找目标元素(包含重复值) .md index af8da3f..2af05c7 100644 --- a/animation-simulation/二分查找及其变种/leetcode 81不完全有序查找目标元素(包含重复值) .md +++ b/animation-simulation/二分查找及其变种/leetcode 81不完全有序查找目标元素(包含重复值) .md @@ -40,10 +40,12 @@ #### **题目代码** +Java Code: + ```java class Solution { public boolean search(int[] nums, int target) { - int left = 0; + int left = 0; int right = nums.length - 1; while (left <= right) { int mid = left+((right-left)>>1); @@ -73,35 +75,3 @@ class Solution { } } ``` - -Go Code: - -```go -func search(nums []int, target int) bool { - l, r := 0, len(nums) - 1 - for l <= r { - m := l + (r - l) / 2 - if nums[m] == target { - return true - } - // 先判断哪边是递增的,再查找范围 - if nums[m] == nums[l] { - l++ - } else if nums[l] < nums[m] { - // 判断target是否在有序的那边就行了。 - if nums[l] <= target && target < nums[m] { - r = m - 1 - } else { - l = m + 1 - } - } else if nums[l] > nums[m] { - if nums[m] < target && target <= nums[r] { - l = m + 1 - } else { - r = m - 1 - } - } - } - return false -} -``` diff --git a/animation-simulation/二分查找及其变种/leetcode153搜索旋转数组的最小值.md b/animation-simulation/二分查找及其变种/leetcode153搜索旋转数组的最小值.md index bd4447d..5ab4c35 100644 --- a/animation-simulation/二分查找及其变种/leetcode153搜索旋转数组的最小值.md +++ b/animation-simulation/二分查找及其变种/leetcode153搜索旋转数组的最小值.md @@ -104,23 +104,3 @@ public: } }; ``` - -Go Code: - -```go -func findMin(nums []int) int { - l, r := 0, len(nums) - 1 - for l < r { - if nums[l] < nums[r] { - return nums[l] - } - m := l + (r - l) / 2 - if nums[l] > nums[m] { - r = m - } else { - l = m + 1 - } - } - return nums[l] -} -``` diff --git a/animation-simulation/二分查找及其变种/leetcode33不完全有序查找目标元素(不包含重复值).md b/animation-simulation/二分查找及其变种/leetcode33不完全有序查找目标元素(不包含重复值).md index b5fc1dd..2258fad 100644 --- a/animation-simulation/二分查找及其变种/leetcode33不完全有序查找目标元素(不包含重复值).md +++ b/animation-simulation/二分查找及其变种/leetcode33不完全有序查找目标元素(不包含重复值).md @@ -89,6 +89,8 @@ #### 题目代码 +Java Code: + ```java class Solution { public int search(int[] nums, int target) { @@ -126,35 +128,3 @@ class Solution { } } ``` - -Go Code: - -```go -func search(nums []int, target int) int { - l, r := 0, len(nums) - 1 - for l <= r { - m := (l + r) / 2 - if target == nums[m] { - return m - } - // 先判断哪边是有序的 - if nums[m] < nums[r] { - // 再判断target在左右哪边 - if target > nums[m] && target <= nums[r] { - l = m + 1 - } else { - r = m - 1 - } - } else { - if target < nums[m] && target >= nums[l] { - r = m - 1 - } else { - l = m + 1 - } - } - } - return -1 -} -``` - -## diff --git a/animation-simulation/二分查找及其变种/leetcode34查找第一个位置和最后一个位置.md b/animation-simulation/二分查找及其变种/leetcode34查找第一个位置和最后一个位置.md index 8460644..a88fb3e 100644 --- a/animation-simulation/二分查找及其变种/leetcode34查找第一个位置和最后一个位置.md +++ b/animation-simulation/二分查找及其变种/leetcode34查找第一个位置和最后一个位置.md @@ -122,6 +122,8 @@ int upperBound(int[] nums, int target) { #### **题目完整代码** +Java Code: + ```java class Solution { public int[] searchRange (int[] nums, int target) { @@ -166,45 +168,3 @@ class Solution { } } ``` - -Go Code: - -```go -func searchRange(nums []int, target int) []int { - upper := upperBound(nums, target) - lower := lowerBound(nums, target) - - if (upper < lower) { - return []int{-1, -1} - } - return []int{lower, upper} -} - -// upperBound 计算上边界 -func upperBound(nums []int, target int) int { - l, r := 0, len(nums) - 1 - for l <= r { - m := l + (r - l) / 2 - if target >= nums[m] { - l = m + 1 - } else if target < nums[m] { - r = m - 1 - } - } - return r -} - -// lowerBound 计算下边界 -func lowerBound(nums []int, target int) int { - l, r := 0, len(nums) - 1 - for l <= r { - m := l + (r - l) / 2 - if target <= nums[m] { - r = m - 1 - } else if target > nums[m] { - l = m + 1 - } - } - return l -} -``` diff --git a/animation-simulation/二分查找及其变种/leetcode35搜索插入位置.md b/animation-simulation/二分查找及其变种/leetcode35搜索插入位置.md index 2a051ca..f5ecfe3 100644 --- a/animation-simulation/二分查找及其变种/leetcode35搜索插入位置.md +++ b/animation-simulation/二分查找及其变种/leetcode35搜索插入位置.md @@ -40,6 +40,8 @@ #### 题目代码 +Java Code: + ```java class Solution { public int searchInsert(int[] nums, int target) { @@ -67,21 +69,3 @@ class Solution { ``` Go Code: - -```go -func searchInsert(nums []int, target int) int { - l, r := 0, len(nums) - 1 - for l <= r { - m := l + (r - l) / 2 - if target == nums[m] { - return m - } - if target < nums[m] { - r = m - 1 - } else if target > nums[m] { - l = m + 1 - } - } - return l -} -``` diff --git a/animation-simulation/二分查找及其变种/二分查找详解.md b/animation-simulation/二分查找及其变种/二分查找详解.md index b8f0b76..b285a24 100644 --- a/animation-simulation/二分查找及其变种/二分查找详解.md +++ b/animation-simulation/二分查找及其变种/二分查找详解.md @@ -94,25 +94,50 @@ target < nums[mid] 则在左半区间继续进行搜索,即 right = mid -1; 下面我们来看一下二分查找的代码,可以认真思考一下 if 语句的条件,每个都没有简写。 +Java Code: + ```java - public static int binarySearch(int[] nums,int target,int left, int right) { - //这里需要注意,循环条件 - while (left <= right) { - //这里需要注意,计算mid - int mid = left + ((right - left) >> 1); - if (nums[mid] == target) { - return mid; - }else if (nums[mid] < target) { - //这里需要注意,移动左指针 - left = mid + 1; - }else if (nums[mid] > target) { - //这里需要注意,移动右指针 - right = mid - 1; - } +public static int binarySearch(int[] nums,int target,int left, int right) { + //这里需要注意,循环条件 + while (left <= right) { + //这里需要注意,计算mid + int mid = left + ((right - left) >> 1); + if (nums[mid] == target) { + return mid; + }else if (nums[mid] < target) { + //这里需要注意,移动左指针 + left = mid + 1; + }else if (nums[mid] > target) { + //这里需要注意,移动右指针 + right = mid - 1; } - //没有找到该元素,返回 -1 - return -1; } + //没有找到该元素,返回 -1 + return -1; +} +``` + +Go Code: + +```go +func binarySearch(nums []int, target, left, right int) int { + //这里需要注意,循环条件 + for left <= right { + //这里需要注意,计算mid + mid := left + ((right - left) >> 1) + if nums[mid] == target { + return mid + } else if nums[mid] < target { + //这里需要注意,移动左指针 + left = mid + 1 + } else if nums[mid] > target { + //这里需要注意,移动右指针 + right = mid - 1 + } + } + //没有找到该元素,返回 -1 + return -1 +} ``` 二分查找的思路及代码已经理解了,那么我们来看一下实现时容易出错的地方 @@ -127,23 +152,48 @@ target < nums[mid] 则在左半区间继续进行搜索,即 right = mid -1; 下面我们来看一下二分查找的递归写法 +Java Code: + ```java public static int binarySearch(int[] nums,int target,int left, int right) { - if (left <= right) { - int mid = left + ((right - left) >> 1); - if (nums[mid] == target) { - //查找成功 - return mid; - }else if (nums[mid] > target) { - //新的区间,左半区间 - return binarySearch(nums,target,left,mid-1); - }else if (nums[mid] < target) { - //新的区间,右半区间 - return binarySearch(nums,target,mid+1,right); - } + if (left <= right) { + int mid = left + ((right - left) >> 1); + if (nums[mid] == target) { + //查找成功 + return mid; + }else if (nums[mid] > target) { + //新的区间,左半区间 + return binarySearch(nums,target,left,mid-1); + }else if (nums[mid] < target) { + //新的区间,右半区间 + return binarySearch(nums,target,mid+1,right); } - //不存在返回-1 - return -1; } + //不存在返回-1 + return -1; +} +``` + +Go Code: + +```go +func binarySearch(nums []int, target, left, right int) int { + + if left <= right { + mid := left + ((right - left) >> 1) + if nums[mid] == target { + //查找成功 + return mid + } else if nums[mid] > target { + //新的区间,左半区间 + return binarySearch(nums, target, left, mid-1) + } else if nums[mid] < target { + //新的区间,右半区间 + return binarySearch(nums, target, mid+1, right) + } + } + //不存在返回-1 + return -1 +} ``` diff --git a/animation-simulation/二分查找及其变种/二维数组的二分查找.md b/animation-simulation/二分查找及其变种/二维数组的二分查找.md index be00baa..8e2799e 100644 --- a/animation-simulation/二分查找及其变种/二维数组的二分查找.md +++ b/animation-simulation/二分查找及其变种/二维数组的二分查找.md @@ -52,6 +52,8 @@ #### 题目代码 +Java Code: + ```java class Solution { public boolean searchMatrix(int[][] matrix, int target) { @@ -83,30 +85,3 @@ class Solution { } } ``` - -Go Code: - -```go -func searchMatrix(matrix [][]int, target int) bool { - if len(matrix) == 0 { - return false - } - row, col := len(matrix), len(matrix[0]) - // 将二维数组拉平为一维。 - l, r := 0, row * col - 1 - for l <= r { - m := l + (r - l) / 2 - // 将一维的坐标转换为二维 - x, y := m / col, m % col - if matrix[x][y] == target { - return true - } else if matrix[x][y] < target { - l = m + 1 - } else if matrix[x][y] > target { - // 二分查找时,把所有的情况都要写出来,避免直接else - r = m - 1 - } - } - return false -} -``` diff --git a/animation-simulation/二分查找及其变种/找出第一个大于或小于目标的索引.md b/animation-simulation/二分查找及其变种/找出第一个大于或小于目标的索引.md index 5f77700..c3484b4 100644 --- a/animation-simulation/二分查找及其变种/找出第一个大于或小于目标的索引.md +++ b/animation-simulation/二分查找及其变种/找出第一个大于或小于目标的索引.md @@ -34,29 +34,57 @@ OK!我们到这一步就能把这个变种给整的明明白白的了,下面我们看一哈程序代码吧,也是非常简单的。 +Java Code: + ```java public static int lowBoundnum(int[] nums,int target,int left, int right) { - while (left <= right) { - //求中间值 - int mid = left + ((right - left) >> 1); - //大于目标值的情况 - if (nums[mid] > target) { - //返回 mid - if (mid == 0 || nums[mid-1] <= target) { - return mid; - } - else{ - right = mid -1; - } - - } else if (nums[mid] <= target){ - left = mid + 1; + while (left <= right) { + //求中间值 + int mid = left + ((right - left) >> 1); + //大于目标值的情况 + if (nums[mid] > target) { + //返回 mid + if (mid == 0 || nums[mid-1] <= target) { + return mid; } + else{ + right = mid -1; + } + + } else if (nums[mid] <= target){ + left = mid + 1; } - //所有元素都小于目标元素 - return -1; } + //所有元素都小于目标元素 + return -1; +} +``` + +Go Code: + +```go +func lowBoundnum(nums []int, target, left, right int) int { + + for (left <= right) { + //求中间值 + mid := left + ((right - left) >> 1); + //大于目标值的情况 + if (nums[mid] > target) { + //返回 mid + if (mid == 0 || nums[mid-1] <= target) { + return mid + }else{ + right = mid -1 + } + + } else if (nums[mid] <= target){ + left = mid + 1 + } + } + //所有元素都小于目标元素 + return -1 +} ``` ## **找出最后一个小于目标元素的索引** @@ -67,27 +95,55 @@ public static int lowBoundnum(int[] nums,int target,int left, int right) { 查找最后一个小于目标数的元素,比如我们的目标数为 7 ,此时他前面的数为 6,最后一个 6 的索引为 5,此时我们返回 5 即可,如果目标数元素为 12,那么我们最后一个元素为 11,仍小于目标数,那么我们此时返回 8,即可。这个变种其实算是上面变种的相反情况,上面的会了,这个也完全可以搞定了,下面我们看一下代码吧。 +Java Code: + ```java public static int upperBoundnum(int[] nums,int target,int left, int right) { - while (left <= right) { + while (left <= right) { - int mid = left + ((right - left) >> 1); - //小于目标值 - if (nums[mid] < target) { - //看看是不是当前区间的最后一位,如果当前小于,后面一位大于,返回当前值即可 - if (mid == right || nums[mid+1] >= target) { - return mid; - } - else{ - left = mid + 1; - } - - } else if (nums[mid] >= target){ - right = mid - 1; + int mid = left + ((right - left) >> 1); + //小于目标值 + if (nums[mid] < target) { + //看看是不是当前区间的最后一位,如果当前小于,后面一位大于,返回当前值即可 + if (mid == right || nums[mid+1] >= target) { + return mid; } + else{ + left = mid + 1; + } + + } else if (nums[mid] >= target){ + right = mid - 1; } - //没有查询到的情况 - return -1; } + //没有查询到的情况 + return -1; +} +``` + +Go Code: + +```go +func upperBoundnum(nums []int, target, left, right int) int { + + for left <= right { + + mid := left + ((right - left) >> 1) + //小于目标值 + if nums[mid] < target { + //看看是不是当前区间的最后一位,如果当前小于,后面一位大于,返回当前值即可 + if mid == right || nums[mid+1] >= target { + return mid + } else { + left = mid + 1 + } + + } else if nums[mid] >= target { + right = mid - 1 + } + } + //没有查询到的情况 + return -1 +} ```