• 剑指offer系列——6.旋转数组的最小数字/搜索旋转排序数组


    Q:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
    输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
    例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
    NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
    C:时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 32M,其他语言64M
    A:

        int minNumberInRotateArray(vector<int> rotateArray) {
            if (rotateArray.size() == 0)
                return 0;
            int a1 = rotateArray[0];
            bool flag = false;
            for (int i = 0; i < rotateArray.size(); i++) {
                flag = true;
                if(rotateArray[i]<a1)
                    return rotateArray[i];
    
            }
            if(flag)
                return rotateArray[0];
        }
    

    T:
    emmmm我想的很简单,既然是旋转数组,那后半的所有数字都比第一个数字小,那只需要找到数组中第一个比数组第一个值小的值不就可以了吗……
    大多大佬用的是二分法,最简单的就是暴力破解,优化就是顺序查找i+1比i小的就可以。
    当然,你会发现……有一个函数叫min函数,还有一个函数叫sort函数……之类的。

    Q:假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
    搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
    你可以假设数组中不存在重复的元素。你的算法时间复杂度必须是 O(log n) 级别。

    示例 1:
    输入: nums = [4,5,6,7,0,1,2], target = 0
    输出: 4

    示例 2:
    输入: nums = [4,5,6,7,0,1,2], target = 3

    A:
    引用:https://blog.csdn.net/qq_29996285/article/details/86602671

    使用二分查找。将数组一分为二,其中一定有一个是有序的,另一个可能是有序,也能是部分有序。此时有序部分用二分法查找。无序部分再一分为二,其中一个一定有序,另一个可能有序,可能无序。

    因此查找过程分为两种情况

    1. target<nums[mid]
    2. target>nums[mid]


    代码:

        public int search(int[] nums, int target) {
            int left = 0;
            int right = nums.length - 1;
            while (left <= right) {
                int mid = (left + right) / 2;
                if (target == nums[mid])
                    return mid;
                else if (target < nums[mid]) {
                    if (nums[left] < nums[mid]) {
                        //说明nums[begin]到nums[mid]为有序递增区间。该区间单纯的二分查找即可
                        if (target >= nums[left]) {
                            right = mid - 1;
                        } else {
                            left = mid + 1;
                        }
                    } else if (nums[left] > nums[mid]) {
                        //说明nums[mid+1]都numerical[nums.size()-1]为有序区间
                        //target肯定在mid前面
                        right = mid - 1;
                    } else if (nums[left] == nums[mid]) {
                        //说明此时数组中只有两个元素。举例:[6,1],target的值为1
                        left = mid + 1;
                    }
                } else if (target > nums[mid]) {
                    if (nums[left] < nums[mid]) {
                        //mid左侧有序
                        left = mid + 1;
                    } else if (nums[left] == nums[mid]) {
                        left = mid + 1;
                    } else if (nums[left] > nums[mid]) {
                        //说明mid到数组末尾为有序递增
                        if (target >= nums[left]) {
                            //说明目标区间在mid左侧,那段无序区间中
                            right = mid - 1;
                        } else {
                            left = mid + 1;
                        }
                    }
                }
            }
            return -1;
        }
    
  • 相关阅读:
    Linked List Cycle leetcode java (链表检测环)
    Remove Duplicates from Sorted List II leetcode java
    Remove Duplicates from Sorted List leetcode java
    Merge Two Sorted Lists leetcode java
    Swap Nodes in Pairs leetcode java
    Median of Two Sorted Array leetcode java
    阿里云最便宜的四种域名注册
    nohup和&后台运行,进程查看及终止
    ipv6转ipv4 NAT64与DNS64基本原理概述
    ros使用pppoe拨号获取ipv6,并且下发IPV6的dns到客户机win7
  • 原文地址:https://www.cnblogs.com/xym4869/p/12239021.html
Copyright © 2020-2023  润新知