1.二分查找标准实现
时间复杂度:O(logN)
public int binarySearch(int[] nums,int target){ int left = 0,right = nums.length - 1; while(left <= right){ int mid = (right - left); if(nums[mid] == target){ return nums[mid]; }else if(nums[mid] < target){ left = mid + 1; }else{ right = mid - 1; } //不存在 return -1; } }
2.求开方
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842...,
由于返回类型是整数,小数部分将被舍去。
class Solution { public int mySqrt(int x) { if(x <= 1) return x; int l= 1,h = x; while(l <= h){ int m = (h - l) /2 + l; int num = x / m; if(m == num){ return m; }else if(m < num){ l = m + 1; }else{ h = m - 1; } } return h; } }
3.给定一个只包含小写字母的有序数组letters 和一个目标字母 target,寻找有序数组里面比目标字母大的最小字母。
在比较时,数组里字母的是循环有序的。举个例子:
如果目标字母 target = 'z' 并且有序数组为 letters = ['a', 'b'],则答案返回 'a'。
如果目标字母 target = 'n' 并且有序数组为 letters = ['m', 'z', 'c', 'f', 'j'] ,则答案返回 'z' 。
示例:
输入:
letters = ["c", "f", "j"]
target = "a"
输出: "c"
输入:
letters = ["c", "f", "j"]
target = "c"
输出: "f"
class Solution { public char nextGreatestLetter(char[] letters, char target) { int l = 0,h = letters.length; while(l < h){ int m = (h -l) / 2+ l; char c = letters[m]; if(c > target){ h = m; }else{ l = m + 1; } } return l == letters.length ? letters[0] : letters[l]; } }
4.目标值在数组中的开始位置
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]
不同点:1、对右边界h的赋值不同,2、循环条件不同(条件1导致),3,返回值不同(条件2导致。由于未检测左右边界相等的情况,因此需要进行判断)
public int[] searchRange(int[] nums, int target) { int l1 = getFirst(nums,target); int l2 = getFirst(nums,target + 1); if(l1 == nums.length || nums[l1] != target){ return new int[]{-1,-1}; } return new int[]{l1,l2 -1}; } private int getFirst(int[] nums,int t){ int l = 0,r = nums.length; while(l < r){ int mid = (r - l) / 2 + l; int num = nums[mid]; if(num >= t){ r = mid; }else{ l = mid + 1; } } //需要验证有无查到 return l; }