数组循环右移衍生的N个问题

前提

将数组循环右移k位

k=0  1 2 3 4 5
k=1  5 1 2 3 4
k=2  4 5 1 2 3
...

问题一

给一正常数组和数字k,返回循环右移k位的数组
方法很多,请看这篇文章

问题二

有一升序数组,现循环右移了k位(k未知),求k的值。

方法一

暴力法,升序数组,找到不符合升序的位置即可。

int Fun(vector<int> &nums){
    for(int i=1;i<nums.size();++i)
        if(nums[i]<nums[i-1]){
            return i;
        }
    return 0;
}

方法二

运用二分查找。高效,当然是最好了解法了。

int Fun(vector<int> &nums){
    if(nums.size() == 0 || nums[0]<nums.back())
        return 0;

    int left = 0;
    int right = nums.size()-1;

    while (left<right){
        int mid = (left+right)/2;

        if(mid == left){
            break;
        }

        if(nums[mid]>nums[left]){
            left = mid;
        }else if(nums[mid]<nums[right]){
            right = mid;
        }
    }

    return left+1;
}

问题三

有一升序数组,循环右移了k位(k未知),现在给一个值target,求在数组中找到target的下标,如果没有则返回-1。

解这道题之前我们先看看正常升序数组的解法(即k=0时),同样运用的是二分查找:

int Fun(vector<int> &nums,int target){
    int left=0;
    int right = nums.size()-1;

    while(left<right){
        int mid = (left+right)/2;
        
        if(mid == left){
            break;
        }
        
        if(nums[mid] == target){
            return mid;
        }else if(nums[mid]<target){
            left = mid;
        }else{
            right = mid;
        }
    }
    return -1;
}

再来考虑右移k位的情况:

int Fun(vector<int> &nums,int target){
    int left = 0;
    int right = nums.size()-1;

    while(left<right){
        int mid = (left + right) / 2;

        if(mid == left){
            break;
        }

        if(target == nums[mid]){
            return mid;
        }else if(target>=nums[left]){
            if(nums[mid]>target){
                right = mid;
            }else{
                if(nums[mid] >nums[left]){
                    left = mid;
                }else{
                    right = mid;
                }
            }
        }else{
            if(nums[mid]<target){
                left = mid;
            }else{
                if(nums[mid] > nums[right]){
                    left = mid;
                }else{
                    right = mid;
                }
            }
        }
    }

    if(target == nums[left])
        return left;
    else if(target == nums[right])
        return right;

    return -1;
}

代码看起来比较繁琐,简化版本:

int Fun(vector<int> &nums,int target){
    int left = 0;
    int right = nums.size()-1;

    while(left<right){
        int mid = (left + right) / 2;

        if(mid == left){
            break;
        }

        if(target == nums[mid]){
            return mid;
        }else if((nums[0] > target) ^ (nums[0] > nums[mid])^ (target > nums[mid])){
            left = mid + 1;
        }else{
            right = mid;
        }
    }

    if(target == nums[left])
        return left;
    else if(target == nums[right])
        return right;

    cout<<left<<","<<right<<endl;
    return -1;
}
发布了63 篇原创文章 · 获赞 73 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/jjwwwww/article/details/100576020
今日推荐