稀疏数组搜索
有个排好序的字符串数组,其中散布着一些空字符串,编写一种方法,找出给定字符串的位置。
示例1:
输入: words = [“at”, “”, “”, “”, “ball”, “”, “”, “car”, “”, “”,”dad”, “”, “”], s = “ta”
输出:-1
说明: 不存在返回-1。
示例2:
输入:words = [“at”, “”, “”, “”, “ball”, “”, “”, “car”, “”, “”,”dad”, “”, “”], s = “ball”
输出:4
提示:
words的长度在[1, 1000000]之间
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sparse-array-search-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
重点总结
1、需要格外注意,字符串数组中存在大量的空字符串,如何解决?
2、字符串比较使用 compareTo() 方法
class Solution {public int findString(String[] words, String s) {//定义左右边界,使用二分查找int left = 0;int right = words.length - 1;while(left<=right){int mid = (left + right)/2;//先向右侧查找第一个非空的字符串while(mid <= right && "".equals(words[mid])){mid++;}//mid>right说明右侧字符串全部为空,此时向mid的左侧查找if(mid>right){mid = (left + right)/2 - 1;while("".equals(words[mid])&&mid>=left){mid--;}//mid<left说明左侧也全部为空字符串,直接返回-1if(mid<left){return -1;}}//根据字符串的比较结果,重新定义左右边界if(words[mid].compareTo(s)==0){return mid;}else if(words[mid].compareTo(s)>0){right = mid -1;}else{left = mid + 1;}}return -1;}}
旋转数组的最小数字
https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
示例 1:
输入:[3,4,5,1,2]
输出:1
示例 2:
输入:[2,2,2,0,1]
输出:0
注意:本题与主站 154 题相同:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/
重点总结
1、暴力法并不是最优解
2、二分查找法的一般初始判定 while(left<right)
3、为什么low + (high - low) // 2而不是 (high + low) // 2
因为low+high在low和high特别大的时候可能会造成溢出,使用减法避免了溢出发生。但是第一种写法也不是 万能的,比如low可以取负数的时候。
class Solution {
public int minArray(int[] numbers) {
int left = 0;
int right = numbers.length -1;
//基本判定流程
while(left<right){
int mid = (left + right)/2;
//mid<right则mid右边是升序排列的,最小值应该在mid左边
if(numbers[mid]<numbers[right]){
right = mid;
//mid>right则旋转前的前半部分在mid的右边
}else if(numbers[mid]>numbers[right]){
left = mid + 1;
//mid=right,无法判断旋转是怎么发生的,所以暴力向前搜索,确定旋转发生的位置
}else{
right -= 1;
}
}
return numbers[left];
}
}
