代码随想录【数组】 ---- 二分查找
- 704.二分查找
- 方法一:二分查找
- 35.搜索插入位置
- 方法一:二分查找
- 34.在排序数组中查找元素的第一个和最后一个位置
- 方法一:二分查找
- 69.x的平方根
- 方法一:袖珍计算器
- 方法二:二分查找
- 方法三:牛顿迭代法
- 367.有效的完全平方数
- 方法一:使用内置函数
- 方法二:暴力
- 方法三:二分查找
- 方法四:牛顿迭代法
704.二分查找
方法一:二分查找
这题就是二分查找的模板题,将二分的模板背上就行了
class Solution {public int search(int[] nums, int target) {int left = 0, right = nums.length - 1;while (left <= right) {int mid = left + right >> 1;if (nums[mid] == target) return mid;else if (nums[mid] > target) right = mid - 1;else if (nums[mid] < target) left = mid + 1;}return -1;}
}
时间复杂度: O(n)
空间复杂度: O(1)
35.搜索插入位置
方法一:二分查找
二分查找 target 的位置,要明确什么时候返回 target 的位置,返回 left 或者是 right - 1
class Solution {public int searchInsert(int[] nums, int target) {int left = 0, right = nums.length - 1;int mid = 0;while (left <= right) {mid = left + right >> 1;if (nums[mid] == target) return mid;else if (nums[mid] > target) right = mid - 1;else if (nums[mid] < target) left = mid + 1;}// return left;return right - 1;}
}
时间复杂度: O(logn)
二分查找的时间复杂度是 O(logn) 级别的
空间复杂度: O(1)
34.在排序数组中查找元素的第一个和最后一个位置
方法一:二分查找
第一次二分查找 nums[mid] >= target 的左边界,第二次二分查找 nums[mid] <= target 的右边界
y总模板
class Solution {public int[] searchRange(int[] nums, int target) {if (nums.length == 0) return new int[]{-1, -1};int l = 0, r = nums.length - 1;while (l < r) {int mid = l + r >> 1;if (nums[mid] >= target) r = mid;else l = mid + 1;}if (nums[r] != target) return new int[]{-1, -1};int L = r;l = 0; r = nums.length - 1;while (l < r) {int mid = l + r + 1 >> 1;if (nums[mid] <= target) l = mid;else r = mid - 1;}return new int[]{L, r};}
}
代码随想录
class Solution {public int[] searchRange(int[] nums, int target) {if (nums.length == 0) return new int[]{-1, -1};int l = 0, r = nums.length - 1;int L = -1, R = -1;while (l <= r) {int mid = l + r >> 1;if (nums[mid] >= target) {L = mid;r = mid - 1;} else {l = mid + 1;}}if (L < 0 || L >= nums.length || nums[L] != target) return new int[]{-1, -1};l = 0; r = nums.length - 1;while (l <= r) {int mid = l + r >> 1;if (nums[mid] <= target) {R = mid;l = mid + 1;} else {r = mid - 1;}}return new int[]{L, R};}
}
时间复杂度: O(logn)
二分查找的时间复杂度是 O(logn) 级别的
空间复杂度: O(1)
69.x的平方根
方法一:袖珍计算器
使用指数函数 exp 和对数函数 log 来代替平方根函数
class Solution {public int mySqrt(int x) {if (x == 0) return 0;int ans = (int)Math.exp(0.5 * Math.log(x));return (long)(ans + 1) * (ans + 1) <= x ? ans + 1 : ans;}
}
时间复杂度: O(1)
空间复杂度: O(1)
方法二:二分查找
由于 x 平方根的整数部分 ans 是满足 k2≤x 的最大 k 值,因此我们可以对 k 进行二分查找,从而得到答案。
class Solution {public int mySqrt(int x) {int left = 0, right = x;int mid = 0, ans = -1;while (left <= right) {mid = left + right >> 1;if (mid * mid <= x) {left = mid + 1;ans = mid;}else right = mid - 1;}return ans;}
}
时间复杂度: O(logn)
二分查找的时间复杂度是 O(logn) 级别的
空间复杂度: O(1)
方法三:牛顿迭代法
没看懂。。。。
后面懂了再更新
367.有效的完全平方数
方法一:使用内置函数
class Solution {public boolean isPerfectSquare(int num) {int x = (int) Math.sqrt(num);return x * x == num;}
}
方法二:暴力
从 1 开始遍历,如果出现了 x * x > num 的情况,说明后面的数也不可能满足情况了,就结束遍历即可
class Solution {public boolean isPerfectSquare(int num) {long x = 1, square = 1;while (square <= num) {if (square == num) return true;x ++ ;square = x * x;}return false;}
}
时间复杂度: O(√n)
n 为 num 的最大值,最多只需遍历 √n + 1 个值
空间复杂度: O(1)
方法三:二分查找
与上个题目的二分查找类似
class Solution {public boolean isPerfectSquare(int num) {int l = 0, r = num;int ans = -1;while (l <= r) {int mid = l + r >> 1;long square = (long) mid * mid;if (square == num) return true;else if (square < num) l = mid + 1;else r = mid - 1;}return false;}
}
方法四:牛顿迭代法
看不懂。。。
但是看答案,与上个题目的牛顿迭代法答案类似,或许直接背一个模板也可以吧。哈哈哈哈哈哈。。。