2020-12-25今日のNiukeand Leetcode ==繰り返し番号付きの順序付き配列のバイナリ検索+ターゲット値を見つけるための回転した順序付き配列+回転した配列の最小数

出典:リンク:https://www.nowcoder.com/practice/7bc4a1c7c371425d9faa9d1b511fe193?tpId = 188 && tqId = 36844&rp = 1&ru = / activity / oj&qru = / ta / job-code-high-
week / question-rankingステートメント:違反した場合誰かの権利、私に連絡してください、そして私はそれを削除します。
私にスプレーする専門家を歓迎します

タイトルの説明繰り返し番号のある順序付き配列のバイナリ検索を実装してください。

出力は、検索値以上の配列内の最初の位置です。配列内にそのような数値がない場合、出力配列の長さは1増加します。

例1
入力5,4、[1,2,4,4,5]
戻り値3
出力位置は1から計算されます

コード、二分された詳細は悪魔です
import java.util.*; 
public class Solution {
    /**
     * 二分查找
     * @param n int整型 数组长度
     * @param v int整型 查找值
     * @param a int整型一维数组 有序数组
     * @return int整型
     */
    public int upper_bound_ (int n, int v, int[] a) { 
        //数组是排序好的, 那么判断最后一个值大于查找值,那么没有查找的意义了
        if(a[n-1] < v) return n+1;
        
        int left = 0, right = a.length;
        
        while(left < right){  
            int mid = left + (right - left)/2;
            if(a[mid] > v) right = mid;
            else if(a[mid] < v) left = mid+1; 
            //这里是应对重复值得思路
            //重复值,就顺序查找
            else{ //a[mid] == v
                while(mid >=0 && a[mid]==v) mid--;
                //为什么是+2???因为此时mid指向小于v的最后一个值,
                //mid+1指向等于v的第一个值,mid+1+1才是 符合“输出位置从1开始计算 ”的结果
                return mid+2;
            }
        }
        //输出位置从1开始计算 所以加1
        return left + 1;
    }
}
タイトルは、ターゲット値を見つけるために回転された順序付き配列を説明します

回転された順序付けられた配列を考えると、事前に配列がどれだけ回転されたかはわかりません
(たとえば、0 1 2 4 5 67は45 6 7 0 1 2になる可能性があります)。
指定されたターゲットを検索します。配列内の値。配列内で見つかった場合はそのインデックスを返し、そうでない場合は-1を返します。
配列に重複がないと仮定します。
例1
入力[1]、0
戻り値-1
例2
入力[ 3、2、1 ]、1
戻り値2

コードポイント:1 Arr [mid] = target 2:右半分が順番になっている3:左半分が順番になっている

回転配列を均等に分割した後、片側は常に次のように順序付けられます。

10 11 12 13 14 15 1 2 3
10 11 15 1 2 3 4 5 6 7 8
順序付けられた側を見つけたら、ターゲットと順序付けられたサブ配列の左右の境界を比較します。次に、左側または右側の意思決定。

import java.util.*; 
public class Solution {
    /**
     * 
     * @param A int整型一维数组 
     * @param target int整型 
     * @return int整型
     */
    public int search (int[] A, int target) {
        // write code here
        int left = 0, right = A.length-1;
        while(left <= right){
            int mid = left + (right-left)/2;
            if(A[mid] == target) return mid;
            else if(A[mid] < A[right]){ //右半部有序
                if(A[mid] < target && target <= A[right]) left = mid+1;
                else right = mid - 1;
            }else{ //左半部有序
                if(target < A[mid] && A[left]<= target) right = mid-1;
                else left = mid + 1;
            }
        } 
        //不要想太多,找不到就返回-1
        return -1;
    }
}  
タイトル説明剣はオファー11を指します。アレイの最小数を回転させます

リンク:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof

配列の最初のいくつかの要素を配列の最後に移動することを、配列の回転と呼びます。昇順配列の回転を入力し、回転した配列の最小要素を出力します。たとえば、配列[3,4,5,1,2]は[1,2,3,4,5]の回転であり、配列の最小値は1です。
例1:
入力:[3,4,5,1,2]
出力:1
例2:
入力:[2,2,2,0,1]
出力:0

コード詳細の二分法

配列の最後の要素xを検討します:最小値の右側の要素はすべてx以下の値
である必要があり、最小値の左側の要素はすべて値がxより大きい必要がありますまたはxに等しい。したがって、この特性に基づく二分探索によって最小値を見つけることができます。

  • 最初のケースはnumbers [pivot] <numbers [high]です。これは、numbers [pivot]が最小値の右側の要素であることを示しているため、バイナリ検索間隔の右半分は無視できます。
  • 2番目のケースはnumbers [pivot]> numbers [high]です。これは、numbers [pivot]が最小値の左側の要素であることを示しているため、バイナリ検索間隔の左半分は無視できます。
  • 3番目のケースはnumbers [pivot] == numbers [high]です。繰り返される要素が存在するため、numbers [pivot]が最小値の左側にあるか右側にあるかを確認できません。
class Solution {
    public int minArray(int[] numbers) {
        int left = 0, right = numbers.length-1;
        while(left <= right){
            int mid = left + (right - left)/2;
            if(numbers[mid] < numbers[right]){
            //这里为什么不是right-1??因为mid这个值是小值,可能是我的所求,所以到带入下一次比较
                right = mid;
            }else if(numbers[mid] > numbers[right]){
                left = mid+1;
            }else{
                right--;
            }
        }
        return numbers[left];
        
    }
}
偉大なる神によって要約された2つのポイント、さまざまな詳細とさまざまなアプリケーション

二分探索アルゴリズムの詳細な説明https://www.cnblogs.com/kyoner/p/11080078.html

おすすめ

転載: blog.csdn.net/qq_45531729/article/details/111680807