整数二分模版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 bool check (int x) {} int bsearch_1 (int l, int r) { while (l < r) { int mid = l + r >> 1 ; if (check (mid)) r = mid; else l = mid + 1 ; } return l; } int bsearch_2 (int l, int r) { while (l < r) { int mid = l + r + 1 >> 1 ; if (check (mid)) l = mid; else r = mid - 1 ; } return l; }
No.367 有效的完全平方数
给定一个正整数 num,编写一个函数,如果 num 是一个完全平方数,则返回 True,否则返回 False。
说明:不要使用任何内置的库函数,如 sqrt。
1 2 3 4 5 6 7 示例 1 : 输入:16 输出:True 示例 2 : 输入:14 输出:False
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution {public : bool isPerfectSquare (int num) { return bsearch (0 , num, num); } bool bsearch (long long l, long long r, long long num) { while (l < r) { long long mid = l + r >> 1 ; if (mid * mid > num) r = mid; else if (mid * mid == num) return true ; else l = mid + 1 ; } if (l > r) return false ; else return (l * l == num) ? true : false ; } };
剑指Offer No.53 0~n-1中缺失的数字
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
1 2 3 4 5 6 7 示例 1 : 输入: [0 ,1 ,3 ] 输出: 2 示例 2 : 输入: [0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,9 ] 输出: 8
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution {public : int missingNumber (vector<int >& nums) { int l = 0 , r = nums.size (); while (l < r) { int mid = l + r >> 1 ; if (nums[mid] != mid) r = mid; else l = mid + 1 ; } return r; } };
No.162 寻找峰值
峰值元素是指其值大于左右相邻值的元素。给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。你可以假设 nums[-1] = nums[n] = -∞。
1 2 3 4 5 6 7 8 9 10 示例 1 : 输入: nums = [1 ,2 ,3 ,1 ] 输出: 2 解释: 3 是峰值元素,你的函数应该返回其索引 2 。 示例 2 : 输入: nums = [1 ,2 ,1 ,3 ,5 ,6 ,4 ] 输出: 1 或 5 解释: 你的函数可以返回索引 1 ,其峰值元素为 2 ; 或者返回索引 5 , 其峰值元素为 6 。
说明:
你的解法应该是 O (logN ) **时间复杂度的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution {public : int findPeakElement (vector<int >& nums) { if (nums.size () == 1 ) return 0 ; return bpeak (0 , nums.size (), nums); } int bpeak (int l, int r, vector<int >& nums) { while (l < r) { int mid = (l + r) >> 1 ; if (mid == nums.size () - 1 ) { if (nums[mid] > nums[mid - 1 ]) return mid; return bpeak (l, mid - 1 , nums); } else if (mid == 0 ) { if (nums[mid] > nums[mid + 1 ]) return mid; return bpeak (mid + 1 , r, nums); } else { if (nums[mid] > nums[mid - 1 ] && nums[mid] > nums[mid + 1 ]) return mid; else { return bpeak (l, mid - 1 , nums) >= 0 ? bpeak (l, mid - 1 , nums) : bpeak (mid + 1 , r, nums); } } } if (l == r && nums[l] > nums[l + 1 ]) return l; else return -1 ; } };
No.33 搜索旋转排序数组
升序排列的整数数组 nums 在预先未知的某个点上进行了旋转(例如, [0,1,2,4,5,6,7] 经旋转后可能变为 [4,5,6,7,0,1,2] )。
请你在数组中搜索 target ,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
1 2 3 4 5 6 7 8 9 10 11 示例 1 : 输入:nums = [4 ,5 ,6 ,7 ,0 ,1 ,2 ], target = 0 输出:4 示例 2 : 输入:nums = [4 ,5 ,6 ,7 ,0 ,1 ,2 ], target = 3 输出:-1 示例 3 : 输入:nums = [1 ], target = 0 输出:-1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution {public : int search (vector<int >& nums, int target) { if (nums.size () == 1 ) return nums[0 ] == target ? 0 : -1 ; int l = 0 , r = nums.size (); while (l < r) { int mid = l + r >> 1 ; if (nums[mid] == target) return mid; else if (nums[mid] >= nums[l]) { if (nums[l]<= target && nums[mid] >= target) r = mid; else l = mid + 1 ; } else { if (nums[mid]<= target && nums[r - 1 ] >= target) l = mid + 1 ; else r = mid; } } if (l == r && l < nums.size () && nums[l] == target) return l; return -1 ; } };