二分法的模版:
类似双指针的操作。
var test = function(nums) {let n = nums.length;let l = 0;let r = n - 1;let m = -1; // -1 代表不指向数组里任何一个位置while (l <= r) {m = l + Math.floor((r - l) / 2);if ('has found') {return m;}if ('condition1') {l = m + 1;continue;}if ('condition2') {r = m;continue;}}return -1;}
367. 有效的完全平方数
但是寻找平方根呢,还有暴力解法:(效果也不差,但是是一点一点去找,比较麻烦)
var isPerfectSquare = function(num) {if (num <= 1) {return true;}for (let i = 0; i * i <= num; i++) {if (i * i === num) {return true;}}return false;};
以下这个二分法提效,从写法上来说也是双指针:
var isPerfectSquare = function(num) {let l = 0;let r = num;while (l <= r) {let m = l + Math.floor((r - l) / 2);let square = m * m;if (num === square) {return true;} else if (num < square) {r = m - 1;} else {l = m + 1;}}return false;};
162. 寻找峰值
这个题的前提,数组之间相邻元素不相同。
不是 和 左右边界比,而是和 相邻左右比较。 ==》 找一种条件可以 二分的形式缩小解的范围
var findPeakElement = function(nums) {let n = nums.length;let l = 0;let r = n - 1;let m = -1; // -1 代表不指向数组里任何一个位置while (l <= r) {m = l + Math.floor((r - l) / 2);// 边界处理很帅呀let left = (m === 0) ? -Infinity : nums[m - 1];let right = (m === n - 1) ? -Infinity : nums[m + 1];if (left < nums[m] && nums[m] > right) {return m;}if (nums[m] < right) {l = m + 1;continue;}if (nums[m] < left) {r = m; // 保留最大值// r = m - 1;continue;}}return -1;}
33. 搜索旋转排序数组

老大哥我费了大力气,终于解出来了,我的思考:就是在找的过程丢掉尽可能多的地方,有效缩小搜索范围。
var search = function(nums, target) {let n = nums.length;if (n === 0) {return -1;}if (n === 1) {return nums[0] === target ? 0 : -1;}// 1、先去找转折点let l = 0;let r = n - 1;let m = -1; // -1 代表不指向数组里任何一个位置while (l <= r) {m = l + Math.floor((r - l) / 2);if (nums[m] === target) {return m;}if (nums[l] <= nums[m]) { // 隔出有序区间[l...m]if (nums[l] <= target && target < nums[m]) { // 在 有序区间[l...m] 中r = m - 1;} else {l = m + 1;}} else { // 隔出有序区间[m...r]if (nums[m] < target && target <= nums[r]) { // 在 有序区间[m...r] 中l = m + 1;} else {r = m - 1;}}}return -1;};
74. 搜索二维矩阵
// 加强版 二分搜索
