704 二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
复制代码
链接:leetcode-cn.com/problems/bi…
解题思路
暴力解决的话就是从头开始遍历数组,但由于这个数组是有序的,所以可以优化成二分查找。即从中间开始查找,根据结果的大小再向左或者向右查找。
二分查找的基本框架:设置一个left指针,一个right指针,mid = floor((left+right)/2),循环条件是left<=right,查看Mid是否是要查找的数,不是的话根据大小移动左右指针缩小范围继续查找。、
时间复杂度是O(logn)
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var search = function(nums, target) {
let right = nums.length - 1;
let left = 0;
while(left <= right){
let mid = Math.floor((right + left) / 2);
if(nums[mid] === target)
return mid;
if(nums[mid] > target){
right = mid - 1;
}else{
left = mid + 1 ;
}
}
return -1;
};
复制代码
69 x的平方根
实现 int sqrt(int x) 函数。计算并返回 x 的平方根,其中 x 是非负整数。由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842...,
由于返回类型是整数,小数部分将被舍去。
复制代码
解题思路
这个题暴力解决的话就是枚举从1到x的数所有数,比较其平方是否和x一样。同上因为有序所以可以优化为二分查找。
这道题的容易忽略的点是如果不是恰好相等,我们要返回比sqrt(x)小的最大的那个整数,所以如果遇到mid * mid < x,就要更新res,这时候肯定是向右寻找的,如果继续寻找依然符合这个条件,那么就会增大res,,从而在结束循环的时候得到res。
/**
* @param {number} x
* @return {number}
*/
var mySqrt = function(x) {
if(x === 0)
return 0;
if(x === 1)
return 1;
let left = 0;
let right = x;
let res = -1;
while(left <= right){
let mid = Math.floor((left + right) / 2);
//let mid = (left + right) >> 1; 也可以用移位
let sum = mid * mid;
if(sum === x)
return mid;
if(sum > x){
right = mid - 1;
}else{
res = mid;
left = mid + 1;
}
}
return res;
};
复制代码
50Pow(x, n)
实现 pow(x, n) ,即计算 x 的 n 次幂函数。
示例 1:
输入:x = 2.00000, n = 10
输出:1024.00000
示例 2:
输入:x = 2.10000, n = 3
输出:9.26100
示例 3:
输入:x = 2.00000, n = -2
输出:0.25000
解释:2-2 = 1/22 = 1/4 = 0.25
复制代码
链接:leetcode-cn.com/problems/po…
解题思路1
暴力计算,但是会超时
/**
* @param {number} x
* @param {number} n
* @return {number}
*/
let myPow = function(x, n) {
if(x === 0)
return 0;
if(n === 0)
return 1;
let sum = 1;
let mi = n > 0 ? n : -n;
while(mi--){
sum *= x;
}
if(n > 0){
return sum;
}else{
return 1 / sum;
}
};
复制代码
解题思路2
快速幂方法 : 正数情况下,如果n为偶数x ^ n = (x * x) ^ (n / 2),如果n为奇数x ^ n = x * x ^ (n - 1)。
/**
* @param {number} x
* @param {number} n
* @return {number}
*/
let myPow = function(x, n) {
if(n === 0)
return 1;
if(n === 1)
return x;
let abs = Math.abs(n);
let isMinus = n !== abs;
let sum = abs % 2 ? x * myPow(x,abs-1): myPow(x*x, abs/2);
return isMinus ? 1 / sum : sum;
};
复制代码