題目一:二分搜索
給定一個 n 個元素有序的(升序)整型數組 nums 和一個目標值 target ,寫一個函數搜索 nums 中的 target,如果目標值存在返回下標,否則返回 -1。
鏈接:https://leetcode-cn.com/problems/binary-search/
思路:
這個是最常規的二分法的問題,不斷地縮小搜索範圍來找到最終的值。以下代碼可以作爲此類題目的模板。
代碼:
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length;
while(left < right) {
int mid = (left + right) >>> 1;
if(target == nums[mid]) {
return mid;
} else if(target < nums[mid]) {
right = mid;
} else {
left = mid + 1;
}
}
return -1;
}
}
題目二:搜索插入位置
給定一個排序數組和一個目標值,在數組中找到目標值,並返回其索引。如果目標值不存在於數組中,返回它將會被按順序插入的位置。
你可以假設數組中無重複元素。
鏈接:https://leetcode-cn.com/problems/search-insert-position/
思路:
思路基本就是二分查找的思路,差別就在於如果沒有找到目標值,返回的是插入的位置。
代碼:
class Solution {
public int searchInsert(int[] nums, int target) {
int left = 0;
int right = nums.length;
while(left < right) {
int mid = (left + right) >>> 1;
if(target == nums[mid]) {
return mid;
} else if(target < nums[mid]) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
}
題目三:X的平方根
實現 int sqrt(int x) 函數。
計算並返回 x 的平方根,其中 x 是非負整數。
由於返回類型是整數,結果只保留整數的部分,小數部分將被捨去。
鏈接:https://leetcode-cn.com/problems/sqrtx/
思路:
X的平方根一定在0~X之間,我們可以採用二分法來解決這個問題。注意這道題要使用long類型,因爲int型的數據平方之後可能超過int型數據的表示範圍。具體到代碼裏,這道題目與前兩道題目的不同點在於判定條件。於此類似的問題不同點可以看作是做判斷的那一步驟不同,思想大同小異。
還有幾點要注意:①求中間的數:最好使用mid = (left + right) >>> 1(左中位數)或者mid = (left + right + 1) >>> 1(右中位數),區分左右中位數的原因是在某些情況下,選擇默認的左中位數,會進入死循環,因此這裏要具體情況具體分析。②while語句的判定條件:最好使用left < right,因爲這樣可以在while循環結束後,不用去考慮left和right的情況,基本是left==right的情況,纔會跳出循環。
代碼:
class Solution {
public int mySqrt(int x) {
if(x == 0) {
return 0;
}
long left = 1;
long right = x;
while(left < right) {
//進入右中位數
long mid = (left + right + 1) >>> 1;
long square = mid * mid;
if(square > x) {
right = mid - 1;
} else {
left = mid;
}
}
return (int)left;
}
}
題目四:有效的完全平方數
給定一個正整數 num,編寫一個函數,如果 num 是一個完全平方數,則返回 True,否則返回 False。
說明:不要使用任何內置的庫函數,如 sqrt。
鏈接:https://leetcode-cn.com/problems/valid-perfect-square/
思路:
思路與上一題基本一致。要注意一點,跳出while循環之後,要對left(right)的數據進行處理,不然會漏掉那個數據。
代碼:
class Solution {
public boolean isPerfectSquare(int num) {
if(num == 0 || num == 1) {
return true;
}
long left = 1;
long right = num / 2;
while(left < right) {
long mid = (left + right) >>> 1;
long square = mid * mid;
if(square == num) {
return true;
} else if(square > num) {
right = mid;
} else {
left = mid + 1;
}
}
if(left * left == num) {
return true;
}
return false;
}
}
題目五:Pow(x, n)
實現 pow(x, n) ,即計算 x 的 n 次冪函數。
鏈接:https://leetcode-cn.com/problems/powx-n/
思路:
採用二分遞歸的思想,,不斷的計算,使用遞歸求出結果。
代碼:
class Solution {
public double myPow(double x, int n) {
if(n == 1) {
return x;
}
if(n == -1) {
return 1 / x;
}
if(n == 0) {
return 1;
}
double temp = myPow(x, n / 2);
double rest = myPow(x, n % 2);
double ans = temp * temp * rest;
return ans;
}
}
參考資料:
https://www.liwei.party/2019/06/19/leetcode-solution-new/search-insert-position/
後續更新細節。