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ビットを返す
ために多くの方法があり、この記事を見てください

質問2

ASCは(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;
}

質問3

ASCは、アレイ、今目標値に回転右kビット(kは未知である)、配列内のインデックスを検索しようとしている対象、または-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 ビュー70000 +

おすすめ

転載: blog.csdn.net/jjwwwww/article/details/100576020