1. 程式人生 > 實用技巧 >二分查詢搜尋要插入位置

二分查詢搜尋要插入位置

leetcode題目:https://leetcode-cn.com/problems/search-insert-position/submissions/
int searchInsert(int* nums, int numsSize, int target){
       int n = numsSize;
        int left = 0, right = n - 1,ans=n;
        while (left <= right) {
            int mid = (right + left) >> 1;
            if (nums[mid]>=target) {
            right 
= mid - 1; ans=mid; } else if (nums[mid]<target){ left = mid + 1; } } return ans; }

以下根據官方題解思考過程: -----》一開始在二分查詢(只是查詢已經存在值的位置)的基礎上, intsearchInsert(int*nums,intnumsSize,inttarget){ intn=numsSize; intleft=0,right=n-1;//ans=n; while(left<right){ intmid=(right+left)>>1; if(target<nums[mid]){ right=mid-1; }elseif(target>nums[mid]){ left=mid+1; } elseif(target==nums[mid]){ returnmid; } } } ----》但是如果不存在就無法查詢位置,如 於是發現在不存在時left和right重合的位置就是要找的插入位置(是比插入值大的一邊) 即mid=left=right>target intsearchInsert(int*nums,intnumsSize,inttarget){ intn=numsSize; intleft=0,right=n-1; while(left<right){ intmid=(right+left)>>1; if(target<nums[mid]){ right=mid-1; }elseif(target>nums[mid]){ left=mid+1; } elseif(target==nums[mid]){ returnmid; } } } intmid=(right+left)>>1;
returnmid; } -----》但是當要插入值比陣列中所有值都大時,如果還是靠right初始為n-1,和while破除條件left==right這種情況就不能考慮到,因為mid==right==left最大為n-1。所以將while的破除條件設為left>right即while(left<=right)。 思考:不考慮插入值比陣列中所有值都大的情況的,其他情況:target能在陣列中找到相同的數,即插入位置為該相同數的位置和 target在陣列中兩個數之間,插入位置為較大數的位置; 1.target能在陣列中找到相同的數(這裡包括了在第一個位置上插入比所有數都小的情況,可以自行舉例如1,3,4,6插0
) 需要經過 : (mid上的數<target )——(mid上的數>target)——(mid上的數==target)或(mid上的數>target)——(mid上的數==target)或(mid上的數<target)——(mid上的數==target)或直接(mid上的數==target)....不管怎麼說最後一定是(mid上的數==target) 2.而插入位置為該相同數的位置和 target在陣列中兩個數之間時,需要經過,這裡舉例: 如1,3,4,6插5(mid上的數<target )——(mid==left==right,mid上的數>target)或如1,3,4,6插2(mid上的數>target,其實得到答案)——(mid==left==right,mid上的數<target,在下一步就要破除了) 以上兩種找到的位置1.mid上的數==target,mid==right==left,2.要麼mid上的數>target,mid==right==left;要麼只是mid上的數>target(如果是先(mid上的數>target)又再 (mid上的數<target )找到(mid==right==left)就不符合了,因為既破除了,又找的不是較大數的位置) 綜上,我們要找的位置都是集中在mid上的數>=target的位置,為了防止破除了也沒找到,我們需要不斷記錄mid上的數>target時mid的值,連帶著mid上的數==target。於是就有 if (nums[mid]>=target) { right = mid - 1; ans=mid; 最後returnans; -----》這個記錄ans的初始值如果為n,即int ans=n;就滿足了當要插入值比陣列中所有值都大時,插入在這些數(下標0~n-1)的最後面,同時target始終>mid上的數,返回ans時保證了為n。 還是要多舉列子驗證過程呀~