所用算法:二分搜索

一维:

704. 二分查找 - 力扣(LeetCode)

算法说明:二分搜索从有序序列中寻找某个给定的值

算法思想:二分法首先从中心位置开始搜索,如果中心位置的元素正好是要找的元素,搜索完成;如果不是,假如中心位置的元素小于要找的元素,则从序列的后半部分找,如果中心位置的元素大于要找的元素则从中心位置的前半部分找。在缩小的范围中再重新确定一个中心位置重复之前的过程。

需要注意的几个问题:

(1)如果一开始时左闭右闭的话(也就是左边和右边都没有超出索引范围,左边起始值是0,右边起始值是size-1),中间过程也应该是左闭右闭的(也就是左边的值和右边的值无论何时都不会包含上一个中间值)

如果一开始时左闭右开的话(也就是左边没有超出索引范围,而右边超出了,左边起始值是0,右边起始值是size),中间过程也应该是左闭右开的(也就是左边的值无论合适都不会包含上一个的中间值,而和右边的值始终都包含上一个的中间值)

(2)到底是小于等于还是小于,这要看是否有意义,当左闭右开的话,右边的值可以等于左边的值,那么小于等于中的等于就有意义,此时应该写小于等于;如果是左闭右开的话,右区间永远不可能等于左区间那么等于就没有意义,那么应该是小于。

 1     int search(vector<int>& nums, int target) {
 2         using vec_index=decltype(nums.size());
 3         vec_index begin=0,end=nums.size();
 4         while(begin<end){
 5             vec_index mid=begin+((end-begin)>>1);
 6             if(target==nums[mid])
 7                 return mid;
 8             else if(target>nums[mid])
 9                 begin=mid+1;
10             else
11                 end=mid;
12         }
13         return -1;
14     }                            

该程序实现:如果没有查找到目标元素就返回-1,否则返回元素所在下标。

二维:

剑指 Offer 04. 二维数组中的查找 - 力扣(LeetCode)

算法思想:从第一行最后一列开始搜索,如果待查找的数比它大则列数不变,行数加一,如果待查找的数比它小则行数不变列数减一。

 1     bool Find(int target, vector<vector<int> > array) 
 2     {
 3         if(array.empty()||array[0].empty()) return false;
 4         int row=0,col=array[0].size()-1,array_size=array.size();
 5         while (row<array_size&&col>=0) 
 6         {
 7             if(target<array[row][col]) --col;
 8             else if(target>array[row][col]) ++row;
 9             else return true;
10         }
11         return false;
12     }

该程序实现在矩阵中查找目标元素,如果查找到则返回true否则返回false。

但是本人又对上面的算法进行改进,即先从最后一列最中间的那个数和待查找的数进行比较,如果待查找的数比中间的那个大,则从中间那行的下一行最后一列的那个元素开始搜索,如果待查找的数比它大则列数不变,行数加一,如果待查找的数比它小则行数不变列数减一。

 1     bool Find(int target, vector<vector<int> > array) {
 2         if(array.empty()||array[0].empty()) return false;
 3         int row=array.size()/2+1,col=array[0].size()-1,array_size=array.size();
 4         if(target==array[row-1][col]) return true;
 5         else if(target<array[row-1][col]) row=0;
 6 
 7         while (row<array_size&&col>=0) 
 8         {
 9             if(target<array[row][col]) --col;
10             else if(target>array[row][col]) ++row;
11             else return true;
12         }
13         return false;
14     }
15 };

这种算法如果一开始待查找的数比中间那个大,则会极大的节省时间。

posted on 2023-04-29 17:13  小凉拖  阅读(38)  评论(0编辑  收藏  举报