var nextGreatestLetter = function(letters, target) { let len = letters.length let l = 0, r = len-1; while(l<=r){ let mid = (l+r)/2; //这里改成 let mid = Math.floor((l+r)/2)就可以了哈哈哈 if(letters[mid]>target){ r = mid-1; }else{ l = mid+1; } } if (l <=len-1){ return letters[l]; }else{ return letters[0]; } }
奇数长度的数组首尾元素索引都为偶数,因此我们可以将 lo 和 hi 设置为数组首尾。
我们需要确保 mid 是偶数,如果为奇数,则将其减 1。
然后,我们检查 mid 的元素是否与其后面的索引相同。
如果相同,则我们知道 mid 不是单个元素。且单个元素在 mid 之后。则我们将 lo 设置为 mid + 2。
如果不是,则我们知道单个元素位于 mid,或者在 mid 之前。我们将 hi 设置为 mid。
一旦 lo == hi,则当前搜索空间为 1 个元素,那么该元素为单个元素,我们将返回它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
var singleNonDuplicate = function(nums) { let lo = 0; let hi = nums.length - 1; while (lo < hi) { let mid = lo + (hi - lo) / 2; if (mid % 2 == 1) mid--; if (nums[mid] == nums[mid + 1]) { lo = mid + 2; } else { hi = mid; } } return nums[lo]; } }
/** * Definition for isBadVersion() * * @param {integer}version number * @return {boolean}whether the version is bad * isBadVersion = function(version) { * ... * }; */
/** * @param {function}isBadVersion() * @return {function} */ var solution = function(isBadVersion) { /** * @param {integer}n Total versions * @return {integer}The first bad version */
returnfunction(n) { let l = 1,r = n; while(l<r){ let mid = Math.floor((l+r)/2); //当时没有加Math.floor(),然后执行代码的时候老是出问题,记住每次都进行一个向下取整 if(isBadVersion(mid) == false){ l = mid+1; }else{ r = mid; } } return r; //这里返回l,r都可以,因为跳出条件的条件是l和r相等 };
var findMin = function(nums) { var left = 0; var right = nums.length - 1; while (left < right) { var mid = (left + right) >> 1; if (nums[mid] > nums[right]) { left = mid + 1; } else { right = mid; } } return nums[left]; };
/** * @param {number[]}nums * @param {number}target * @return {number[]} */ var searchRange = function(nums, target) { let l = 0,r = nums.length-1; while(l<=r){ mid = Math.floor((l+r)/2); if(nums[mid]==target){ let start = mid; let end = mid; while(end<=r&&nums[end] == nums[end+1]){end++;} while(start>=l&&nums[start] == nums[start-1]){start--;} return [start,end]; }elseif(nums[mid]<target){ l = mid+1; }else{ r = mid-1; } } return [-1,-1] };
解法二:
使用js自带的api解决此题,复杂度较高。
1 2 3 4 5
var searchRange = function(nums, target) { let start = nums.indexOf(target); //查找数组中第一个值为target的索引 let end = nums.lastIndexOf(target); //查找数组中最后一个值为target的索引 return [start,end] }
解法三:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
var searchRange = function(nums, target) { let left = 0, right = nums.length - 1, mid; while (left <= right) { mid = (left + right) >> 1; if (nums[mid] === target) break; //其实和第一种解法一样,只是这里用了break的方法,碰到与目标值相等的值后直接跳出循环,然后查找数组中与target值相等的有几个。 if (nums[mid] > target) right = mid - 1; else left = mid + 1; } if(left > right) return [-1, -1]; let i = mid, j = mid; while(nums[i] === nums[i - 1]) i--; while(nums[j] === nums[j + 1]) j++; return [i, j];