二分法应用实例

匿名 (未验证) 提交于 2019-12-03 00:05:01

二分法的时间复杂度O(log(n))O(\log(n)),直接遍历时间复杂度是O(n)O(n)。倘若数组的长度是2322^{32},也就是 4294967296,那么在O(n)O(n)的最坏的情况下,你要查找4294967296这么多次,如果是用二分的话,最坏查找32次就可以了。
解题模板:
模板只是起到辅助作用,至于真正用的话,还是需要思考如何灵活使用它。
对于有序的数组,可以考虑使用二分,直接暴力遍历,感觉过不了呢。

int start = 0, end = nums.size() - 1; while(start + 1 < end) { 	int mid = start + (end - start) / 2; 	if( ... ) 	{ 		start = mid; 	} 	else 	{ 		end = mid; 	} 	//灵活变动,但需要单独判断,可能并行判断,可能有优先级去判断 	if...start.... 	if...end.... } 

0.第一个错误版本(leetcode 278)

// Forward declaration of isBadVersion API. bool isBadVersion(int version);  class Solution { public:     int firstBadVersion(int n) {         int start = 1, end = n;         while(start+1 < end)         {             int mid = start + (end - start) / 2;             if(!isBadVersion(mid))             {                 start = mid;             }             else             {                 end = mid;             }         }         if(isBadVersion(start))         {             return start;         }         return end;     } }; 

1.在排序数组中查找元素的第一个和最后一个位置(leetcode 34)

class Solution { public:     vector<int> searchRange(vector<int>& nums, int target) {         //for(int i = 0; i < 6; i++)printf("%d ",nums[i]);printf("\n");         vector<int> ret(2,-1);         int size = nums.size();         if(size == 0)             return ret;                  // find front         int start = 0, end = size - 1;         while(start+1 < end)         {             int mid = start + (end - start) / 2;             //printf("start is %d, end is %d, mid is %d \n",start,end,mid);             if(nums[mid] >= target)             {                 end = mid;             }             else             {                 start = mid;             }         }         if(nums[start] == target)         {             ret[0] = start;         }             else if(nums[end] == target)         {             ret[0] = end;         }                  //find back         start = 0, end = size - 1;         while(start+1 < end)         {             int mid = start + (end - start) / 2;             //printf("start is %d, end is %d, mid is %d \n",start,end,mid);             if(nums[mid] <= target)             {                 start = mid;             }             else             {                 end = mid;             }         }         if(nums[end] == target)         {             ret[1] = end;         }             else if(nums[start] == target)         {             ret[1] = start;         }                return ret;     } }; 

2.搜索二维矩阵(leetcod 74)

class Solution { public:     bool searchMatrix(vector<vector<int>>& matrix, int target) {         if(matrix.empty() || matrix[0].empty())             return false;                  int row = matrix.size();         int startRow = 0, endRow = row - 1;         while(startRow + 1 < endRow)         {             int mid = startRow + (endRow - startRow)/2;             if(matrix[mid][0] == target)             {                 return true;             }             else if(matrix[mid][0] < target)             {                 startRow = mid;             }             else             {                 endRow = mid;             }         }                  int selectRow = 0;         if(matrix[endRow][0] <= target)         {             selectRow = endRow;         }         else         {             selectRow = startRow;         }                  int startCol = 0, endCol = matrix[0].size() - 1;         while(startCol+1 < endCol)         {             int mid = startCol + (endCol - startCol)/2;             if(matrix[selectRow][mid] == target)             {                 return true;             }             else if(matrix[selectRow][mid] < target)             {                 startCol = mid;             }             else             {                 endCol = mid;             }         }         if(matrix[selectRow][startCol] == target || matrix[selectRow][endCol] == target)            return true;         return false;     } }; 

3.搜索二维矩阵 III(leetcod 240)

class Solution { public:     bool searchMatrix(vector<vector<int> >& matrix, int target) {         if(matrix.empty() || matrix[0].empty())             return false;         int numOfFind = matrix.size() < matrix[0].size() ? matrix.size():matrix[0].size();         //printf("numOfFind is %d\n",numOfFind);         for(int i = 0; i < numOfFind; i++)         {             //printf("i is %d\n",i);             bool upDown = find(matrix, i, target, true);             bool leftRight = find(matrix, i, target, false);             //printf("upDown is %d, leftRight is %d\n",upDown,leftRight);             if(upDown || leftRight)                 return true;         }                  return false;     }      private:     bool find(vector<vector<int> >& matrix, int i, int target, bool isFindRow)     {         int start = i, end = isFindRow?matrix.size()-1:matrix[0].size()-1;         //printf("isFindRow is %d\n",isFindRow);         while(start + 1 < end)         {             int mid = start + (end - start)/2;             //printf("start is %d, end is %d, mid is %d\n", start, end, mid);             if(isFindRow)             {                 if(matrix[mid][i] < target)                 {                     start = mid;                 }                 else if(matrix[mid][i] > target)                 {                     end = mid;                 }                 else                 {                     return true;                 }             }             else             {                 if(matrix[i][mid] < target        
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!