• 33. Search in Rotated Sorted Array


    题目:

    Suppose a sorted array is rotated at some pivot unknown to you beforehand.

    (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

    You are given a target value to search. If found in the array return its index, otherwise return -1.

    You may assume no duplicate exists in the array.

    链接: http://leetcode.com/problems/search-in-rotated-sorted-array/

    题解:Rotated array中查找值,使用Binary Search,要注意数组是向左shift或者是向右shift,保持在一个单调递增的部分进行查找。

    简单的三种情况 - 1) 不平移   1234567

            2) 向左3位  4567123

               3) 向右3位   5671234 

    时间复杂度 O(logn), 空间复杂度 O(1)

    public class Solution {
        public int search(int[] nums, int target) {         //binary search
            if(nums == null || nums.length == 0)
                return 0;
            int lo = 0, hi = nums.length - 1;
            
            while(lo <= hi) {
                int mid = lo + (hi - lo) / 2;
                if(nums[mid] == target)
                    return mid;
                else if(nums[mid] < nums[hi]) {            // right half sorted
                    if(target > nums[mid] && target <= nums[hi])        //e.g. target = 5,  1-2-3-4-5-6-7,  6-7-1-2-3-4-5
                        lo = mid + 1;
                    else                                                //e.g  target = 5,  5-6-7-1-2-3-4
                        hi = mid - 1;
                } else {                                  // left half sorted
                    if(target < nums[mid] && target >= nums[lo])        //e.g. target = 3,  3-4-5-6-7-1-2
                        hi = mid - 1;
                    else                                                //e.g. target = 3,  4-5-6-7-1-2-3 
                        lo = mid + 1;
                }
            }
            
            return -1;
        } 
    }

    二刷:

    Java:

    反而写得比较复杂了。不过原理就是用nums[mid]和nums[right]进行比较,保持mid左边或者右边一段是有序的,再根据target与 nums[mid] 和nums[right]的关系来完成进一步的二分。 看到3天前StefanPochmann又发了一个帖子,可以加入Integer.MIN_VALUE或者Integer.MAX_VALUE来进行普通二分,非常巧妙,放在reference里以后看。

    Time Complexity - O(logn), Space Complexity - O(1)

    public class Solution {
        public int search(int[] nums, int target) { // assume no duplicates
            if (nums == null || nums.length == 0) {
                return -1;
            }
            int lo = 0, hi = nums.length - 1;
            while (lo <= hi) {
                int mid = lo + (hi - lo) / 2;
                if (target == nums[mid]) {
                    return mid;
                } else if (target < nums[mid]) {
                    if (nums[mid] < nums[hi]) {  // right part sorted
                        hi = mid - 1;
                    } else{
                        if (target <= nums[hi]) {
                            lo = mid + 1;
                        } else {
                            hi = mid - 1;
                        }
                    }
                } else {
                    if (nums[mid] < nums[hi]) {
                        if (target > nums[hi]) {
                            hi = mid - 1;
                        } else {
                            lo = mid + 1;
                        }
                    } else {
                        lo = mid + 1;
                    }
                }
            }
            return -1;
        }
    }

    题外话:

    今天被Two Sigma的Recruiter联系,聊了一下之后感觉对方十分专业。打算递交简历以后再拖延一段时间,来进行复习准备。更需要练习的是反应速度,脑力,分析能力,交流能力,专注程度,以及做题的速度和准确度。

    三刷:

    使用了一刷的逻辑。还是Binary Search,就是先判断是否nums[mid] == target,再判断这个sorted array是向左还是右平移,哪一部分仍然是有序的。接下来根据上面的信息来判断如何二分。

    Java:

    Time Complexity - O(logn), Space Complexity - O(1)。

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

    4/3/2016: 今天去Edison取税,之后和地图君一块吃了一家H-Mart附近的东北菜馆。人很少,周日中午加上我们一共就三桌,不过味道挺不错。 吃了烤羊肉串,豆腐脑,煎饼果子,韭菜盒子,锅包肉,地三鲜,酸菜排骨等等,特别对我的胃口。咸豆腐脑可能还是来美帝这么久第一次吃到,好羡慕住附近的朋友们。地图君坚持付了帐,下次再这样我要生气了。

    Reference:

    https://leetcode.com/discuss/80659/clever-idea-making-it-simple 

    https://leetcode.com/discuss/41134/java-ac-solution-using-once-binary-search

  • 相关阅读:
    python爬取动态网页数据,详解
    几行代码轻松搞定python的sqlite3的存取
    14、Iterator跟ListIterator的区别
    13、Java菜单条、菜单、菜单项
    12、借助Jacob实现Java打印报表(Excel、Word)
    11、借助POI实现Java生成并打印excel报表(2)
    10、借助POI实现Java生成并打印excel报表(1)
    9、JcomboBox下拉框事件监听
    8、单选按钮(JRadioButton)和复选框(JCheckBox)
    java swing 添加 jcheckbox复选框
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4435871.html
Copyright © 2020-2023  润新知