力扣---数组篇之二分查找
一、基本概念
- 数组是存放在连续内存空间上的相同类型数据的集合
- 数组下标都是从 0 开始的
- 数组内存空间的地址是连续的
- 数组的元素无法删除,只能覆盖
二、刷题
值得注意的是,利用二分法解题时要注意边界问题也就是区间问题【确定是左闭右闭还是左闭右开】
1. 704_二分查找
- 方法一:利用二分法求解,
需要注意 JavaScript 的除法运算 " / " 返回小数
,而我们需要整数且是向下取整,因此利用JavaScript的内置函数Math.floor()
// 左闭右闭 var search = function (nums, target) { var left = 0; var right = nums.length - 1; var mid = 0; while (left <= right) { mid = Math.floor((left + right) / 2); // mid = left + ((right - left) >> 1); 位运算可以防止大数溢出 if (nums[mid] > target) { right = mid - 1; } else if (nums[mid] < target) { left = mid + 1; } else { return mid; } } return -1; }; // 左闭右开 var search = function (nums, target) { var left = 0; var right = nums.length; var mid = 0; while (left < right) { mid = Math.floor((left + right) / 2); // mid = left + ((right - left) >> 1); if (nums[mid] > target) { right = mid; } else if (nums[mid] < target) { left = mid + 1; } else { return mid; } } return -1; };
- 方法二:直接利用 JavaScript 的内置函数【但是违背了题目要考察的知识】
var search = function(nums, target) { return nums.indexOf(target); };
2. 35_搜索插入位置
- 方法一:利用二分法求解,在查找过程中如果不存在目标值,那么无论中间值大于还是小于目标值,
left
的值最后永远会指向目标值应该插入的位置【时间复杂度:O(log n);空间复杂度:O(1)】var searchInsert = function(nums, target) { var left = 0; var right = nums.length - 1; while (left <= right) { var mid = Math.floor((left + right) / 2); // mid = left + ((right - left) >> 1); if (nums[mid] > target) { right = mid - 1; } else if (nums[mid] < target) { left = mid + 1; } else { return mid; } } return left; };
- 方法二:暴力解法【时间复杂度:O(n);空间复杂度:O(1)】
var searchInsert = function(nums, target) { for (var i = 0; i < nums.length; i++) { if(nums[i] >= target) { return i; } } return nums.length; };
3. 34_在排序数组中查找元素的第一个和最后一个位置
- 方法一:分别查找左右边界,查找过程中
right
指向的索引永远会比left
指向的索引小一【值得反复推敲】var searchRange = function (nums, target) { var searchLeftBorder = function (nums, target) { var left = 0; var right = nums.length - 1; var leftBorder = -2; while (left <= right) { var mid = left + ((right - left) >> 1); if (nums[mid] >= target) { right = mid - 1; leftBorder = right; } else { left = mid + 1; } } return leftBorder; } var searchRightBorder = function (nums, target) { // 不包含target的右边界 var left = 0; var right = nums.length - 1; var rightBorder = -2; while (left <= right) { var mid = Math.floor((left + right) / 2); if (nums[mid] > target) { right = mid - 1; } else { left = mid + 1; rightBorder = left; } } return rightBorder; } var leftBorder = searchLeftBorder(nums, target); var rightBorder = searchRightBorder(nums, target); if (leftBorder === -2 || rightBorder === -2) { return [-1, -1]; } if (rightBorder - leftBorder > 1) { return [leftBorder + 1, rightBorder - 1]; } return [-1, -1]; };
4. 69_x的平方根
- 方法一:二分法求解
var mySqrt = function(x) { var l = 1; var r = x; while (l <= r) { var mid = l + ((r - l) >> 1) if (mid * mid > x) { r = mid - 1; } else if (mid * mid < x) { l = mid + 1; } else { return mid; } } return r; };
- 方法二:遍历
var mySqrt = function(x) { for (var i = 1; i <= x; i++) { if (i * i <= x && (i+1) * (i+1) > x) { return i; } } };
5. 367_有效的完全平方数
- 方法一:二分法求解
var isPerfectSquare = function (num) { var l = 1; var r = num; while (l <= r) { var mid = l + ((r - l) >> 1) if (mid * mid > num) { r = mid - 1; } else if (mid * mid < num) { l = mid + 1; } else { return true; } } return false; };
总结
每天学习一点点,快乐就会多一点
以上就是 数组篇之二分查找 刷题记,小梁加油哦!!!