二分查找搜索要插入位置
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; }
以下根据官方题解思考过程:
-----》一开始在二分查找(只是查找已经存在值的位置)的基础上,
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 (target < nums[mid]) {
right = mid - 1;
} else if (target > nums[mid]){
left = mid + 1;
}
else if (target == nums[mid]){
return mid;
}
}
}
----》但是如果不存在就无法查找位置,如 于是发现在不存在时left和right重合的位置就是要找的插入位置(是比插入值大的一边)
即mid=left=right>target
int searchInsert(int* nums, int numsSize, int target){
int n = numsSize;
int left = 0, right = n - 1;
while (left < right) {
int mid = (right + left) >> 1;
if (target < nums[mid]) {
right = mid - 1;
} else if (target > nums[mid]){
left = mid + 1;
}
else if (target == nums[mid]){
return mid;
}
}
}
int mid = (right + left) >> 1;
return mid;
}

-----》但是当要插入值比数组中所有值都大时,如果还是靠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;
最后return ans;
-----》这个记录ans的初始值如果为n,即int ans=n;就满足了当要插入值比数组中所有值都大时,插入在这些数(下标0~n-1)的最后面,同时target始终>mid上的数,返回ans时保证了为n。
还是要多举列子验证过程呀~
转载请注明喔~
posted on 2020-12-06 15:36 wang_dahua 阅读(171) 评论(0) 收藏 举报