leetcode 1-search

1. Search Insert Position

 1 class Solution {
 2 public:
 3     int searchInsert(int A[], int n, int target) {
 4         int left=0,right=n-1;
 5         while(left<=right)
 6         {
 7             int mid=left+(right-left)/2;
 8             if(A[mid]==target) return mid;
 9             if(A[mid]<target)
10                 left=mid+1;
11             else right=mid-1;
12         }
13         return left;
14     }
15 };

当循环结束时,如果没有找到目标元素,那么left一定停在恰好比目标大的index上,right一定停在恰好比目标小的index上.

特殊点的例子:当在{1,2,3,4,5}里执行二分查找找0时,此时的left=0, right=-1.(left和right也是挺拼的,为了比target大/小,不惜越界。)

这个规律非常有用,合理利用left和right在未找到target的情况下退出while循环时的特性,能解决很多问题,尤其体现在实现upperBound和lowerBound函数时。如果要利用left或right,需要保证target不在当前区间内,这样才能让while循环以未找到target的状态退出。为了实现这一点,我们需要在即使发现target==A[mid]的情况下仍然假装没看见,继续缩小搜索范围。

因此如果要在二分搜索的基础上计算bound的话,其实就是怎么处理那几个值为target的元素的问题。也就是是否把这部分值恰好为target的元素纳入下一轮搜索范围。(二分搜索本质上就是不断缩小搜索范围)。

以upperBound为例。upperBound函数是找[left,right]内第一个大于target的元素下标------所以值为target的元素肯定要排除在搜索范围之外。这样当A[mid]==target时我们仍将其排除在搜索范围外,即让low=mid+1。一直到搜索范围里已经没有值为target的元素了,此时根据二分查找的性质,当区间里没有找到target时,while循环退出后low指向刚好大于target的位置,high指向刚好小于target的位置。所以此时我们返回low即为刚好大于target的位置,即——第一个大于target的位置。

lowerBound同理。lowerBound是寻找[left,right]内第一个值不小于target的元素下标。“不小于”target的不好求,但刚好小于target的那个元素位置比较好求,因为这就是right的返回值。所以我们按照上述思路,在遇到A[mid]==target的情况下仍假装看不见,继续缩小搜索范围,直到当前范围里没有了target,最终循环退出时right就指向值刚好小于target的元素位置。而(right+1)即为不小于target的元素下标。

lowerBound和upperBound的实现代码在下一题代码中。

What if there are duplicates?

2. Search for a Range

 1 class Solution {
 2 public:
 3     vector<int> searchRange(int A[], int n, int target) {
 4         int left=0,right=n-1;
 5         vector<int> res(2,-1);//[-1,-1]是默认值
 6         while(left<=right)
 7         {
 8             int mid=left+(right-left)/2;
 9             if(A[mid]<target)
10                 left=mid+1;
11             else if(A[mid]>target)
12                 right=mid-1;
13             else
14             {
15                 res[0]=lowerBound(A,left,mid,target);
16                 res[1]=upperBound(A,mid,right,target)-1;//别忘了减1
17                 return res;
18             }
19         }
20         return res;//这一句别忘了。当查找失败时返回[-1,-1].
21     }
22 private:
23     int upperBound(int A[], int left, int right, int target)
24     {
25         int low = left, high = right;
26         while (low <= high)
27         {
28             int mid = low + (high - low) / 2;
29             if (A[mid] <= target)
30                 low = mid + 1;
31             else
32                 high = mid - 1;
33         }
34         return low;
35     }
36     int lowerBound(int A[], int left, int right, int target)
37     {
38         int low = left, high = right;
39         while (low <= high)
40         {
41             int mid = low + (high - low) / 2;
42             if (A[mid] >= target)
43                 high = mid - 1;
44             else
45                 low = mid + 1;
46         }
47         return high + 1;
48     }
49 };

lowerBound和upperBound与binarySearch之间的关系上一题里已经分析过了。

注意几个小细节,已在注释中标明。细节决定成败,bug-free需要谨小慎微。

3. Search in Rotated Sorted Array

 1 class Solution {
 2 public:
 3     int search(int A[], int n, int target) {
 4         int left=0,right=n-1;
 5         while(left<=right)
 6         {
 7             int mid=left+(right-left)/2;
 8             if(A[mid]==target) return mid;
 9             if(A[mid]<A[right])//说明右半段是有序的
10             {
11                 if(target>A[mid]&&target<=A[right])
12                     left=mid+1;
13                 else
14                     right=mid-1;
15             }
16             else
17             {
18                 if(target>=A[left]&&target<A[mid])
19                     right=mid-1;
20                 else
21                     left=mid+1;
22             }
23         }
24         return -1;
25     }
26 };

最关键的把握这个规律:"总有一半是有序的,而且和另一半无区间重叠"。code ganker的总结很好。

时间: 2024-10-09 08:35:09

leetcode 1-search的相关文章

[LeetCode] 034. Search for a Range (Medium) (C++/Java)

索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 035. Search for a Range (Medium) 链接: 题目:https://leetcode.com/problems/search-for-a-range/ 代码(github):https://github.com/illuz/leetcode 题意: 在有序数组中找到一个数的范围.(由于数

【LeetCode】Search Insert Position (2 solutions)

Search Insert Position Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. You may assume no duplicates in the array. Here are few examples.[1,3,5,

[LeetCode] 035. Search Insert Position (Medium) (C++)

索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 035. Search Insert Position (Medium) 链接: 题目:https://leetcode.com/problems/search-insert-position/ 代码(github):https://github.com/illuz/leetcode 题意: 要把一个数有序插入到一

【Leetcode】Search a 2D Matrix

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: Integers in each row are sorted from left to right. The first integer of each row is greater than the last integer of the previous ro

[LeetCode] Word Search [37]

题目 Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be

LeetCode: Word Search [079]

[题目] Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not

【LeetCode】- Search Insert Position(查找插入的位置)

[ 问题: ] Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. You may assume no duplicates in the array. 翻译:给你一个排好序的数组和一个目标值,请找出目标值可以插入数组的位置. [ 分析: ]

Java for LeetCode 081 Search in Rotated Sorted Array II

Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this affect the run-time complexity? How and why? Write a function to determine if a given target is in the array. 解题思路: 参考Java for LeetCode 033 Search in Rota

LeetCode Solutions : Search in Rotated Sorted Array II

Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this affect the run-time complexity? How and why? Write a function to determine if a given target is in the array. Java Solution ( refer to my blog LeetCode So

[LeetCode] 033. Search in Rotated Sorted Array (Hard) (C++)

索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 033. Search in Rotated Sorted Array (Hard) 链接: 题目:https://leetcode.com/problems/search-in-rotated-sorted-array/ 代码(github):https://github.com/illuz/leetcode 题