FTPrep, 33 Search in Rotated Sorted Array

来源:互联网 发布:郭达 刁光斗 知乎 编辑:程序博客网 时间:2024/06/04 18:22

今晚状态不错,注意力非常集中,于是很冲动地说要把每道题都one-time bug-free,直到成功

下面的代码写了两遍,都进行秒表计时,4'58'' AC

代码如下,最为基本的二分法的搜索,在判断完mid是否相等之后,不能马上进行left 和 right的更新,因为还不能确定target 到底在哪一边,所以还要进行哪一边order的判断。在进行左边是否ordered的时候要注意可以有 [left]==[mid] 的情况,那就是两个左边相等时。。。有了ordered side 的判断后,然后看target是不是在这个ordered side 的范围,是的话相应改变right,或者left,都是在mid的基础上加减一。

public class Solution {    public int search(int[] nums, int target) {        int len=nums.length;        if(len==0) return -1;        int left=0, right=len-1;        while(left<=right){            int mid= left+(right-left)/2;            if(target==nums[mid]) return mid;            if(nums[left]<=nums[mid]){                if(target>=nums[left] && target<nums[mid]) right=mid-1;                else left=mid+1;            }            else{                if(target>nums[mid] && target<=nums[right]) left=mid+1;                else right=mid-1;            }        }        return -1;    }}

下面来试试递归的方法,其实想想,while循环的本质上做的一件事请就是update 两个index,既然是不断更新两个index,且更新就两种情况(有限种情况时都适用),这就适合用递归来做,同时while的退出条件也就是相应的递归结束的条件!

简而言之:while 内部的update不复杂时,之后几种情况的时候,就是可以用递归来替换的时候。

下面的代码用了9'40'',直接以上面的代码为算法参照,做好了几个关键要素的一一对应,直接在更新 两个index的地方,进行return 递归调用,call函数本身,又让我想起来linklist的几乎所有题都可以用递归来解决就是因为把以后的作为一个整体用递归call自身来对待,然后就是处理好当面情况就好。这里是同样的,当确定好了target的范围之后,也就可以更新了,也就是说是可以递归call自身了,然后当前的情况有四种可能性,每种可能性都进行return,那么也完成了所有的当前任务。就是这么理解就够了!!!

当前情况就是4个分支,两层判断,两个if,然后4个分支,每个都进行一次return,那就搞定所有当前情况了。

另外说明的是,现在我建立的惩罚机制,如果有bug,那么就必须fix bug之后,在把代码从头来一遍,然后一次bug-free,这就要求我极度耐心,把代码检查完了,觉得真的没有问题了,检查不出来明显错误了,才提交,这样其实是省时间的。否则错过一次就要重来。。必须进行这种变态的训练才能够真正的有所提高。什么所谓的高薪,competing offer,去尼玛的,不要再去谈论这种问题了。focus在实力上,这才是王道,不管去面试哪个公司,最后去哪工作这都是不变的。不要再讨论薪水之类的SB话题了。be strong be solid

public class Solution {    public int search(int[] nums, int target) {        int len=nums.length;        if(len==0) return -1;        return helper(nums, 0, len-1, target);    }        private int helper(int[] nums, int left, int right, int target){        if(left>right) return -1;                int mid= left + (right-left)/2;        if(target== nums[mid]) return mid;        if(nums[left]<=nums[mid]){   // when two index are neighboers            if(target>=nums[left] && target<nums[mid]) return helper(nums, left, mid-1, target);            else return helper(nums, mid+1, right, target);        }        else{            if(target>nums[mid]&&target<=nums[right]) return helper(nums, mid+1, right, target);            else return helper(nums, left, mid-1, target);        }    }}

有意思的是,递归的方法效率高得多,80%+,普通的二分法才40%。有可能是递归的算法每次缩小范围进行的判断更简单?其实不太清楚过程。TODO: figure out 速度问题。







阅读全文
0 0
原创粉丝点击