前面5道题都是围绕 rotated sorted array来展开,是二分法解题的一种拓展。跳出这个 rotated sorted array 是否还有别的二分法拓展解题呢?我想到了两个:1,本题,first bad version;2,two sum
two sum 很明显,先进行排序,得到了sort array;first bad version呢?本质上也是一样的,左边所有都是good version,右边所有都是bad version,那么也是一种排序;再进一步想,我是不是可以自创一道题类似于first bad version这道题,比如一个array,所有的负数都在左边,所有的非负数都在右边,找出第一个非负整数!这本质上和first bad version一样的,姑且称之 二元排序。我自己可以写一个试试,放在MyElipse里。
之前的First Bad Version题的代码如下,要注意的就是 要对左右两个index,应改为long,因为又可能array length很大,在left+right越界了。
/* The isBadVersion API is defined in the parent class VersionControl.
boolean isBadVersion(int version); */
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
long currBad=n;
long prevGood=1;
while(prevGood<currBad){
long mid=(prevGood+currBad)/2;
if(isBadVersion((int)mid)) currBad=mid;
else prevGood=mid+1;
} // where while loop ends, prevGood==currBad, so we find the 1st bad
return (int)currBad;
}
}
今天的代码加分析:
/* The isBadVersion API is defined in the parent class VersionControl.
boolean isBadVersion(int version); */
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
long left=1; // left 的意义是:其左边的数一定不是bad version,如果面试时碰到这题,一定要解释这个
long right=n;
while(left<right){
int mid=(int)((left+right)/2); // 这里要在(int)后面的整体再多打一层括号,否则计算顺序出错。
if(isBadVersion(mid)) right=(long)mid;
else left=(long)(mid+1);
}
return (int)left; // same as return (int)right;
}
}
自己出题firstNonNeg的代码如下:
public class FristNonNeg {
public static int firstNonNeg(int[] nums){
int left=0;
int right=nums.length-1;
while(left<right){
int mid=(right+left)/2;
if(nums[mid]>=0) right=mid;
else left=mid+1;
}
return nums[left];
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] nums= new int[]{-3, -3, -5, -31, -324, 6, 1};
System.out.println(firstNonNeg(nums));
}
}