704. 二分查詢
這個之前有寫過,最重要的就是把握住要去搜尋的區間的形式,包括左閉右閉以及左閉右開兩種
class Solution {
public int search(int[] nums, int target) {
int left = 0, right = nums.length;
while(left < right){ // 左閉右開的版本,結果儲存在[left, right)中,因此如果最終left >= right,就意味著沒有找到結果
int mid = (left + right) / 2;
if(nums[mid] > target) { right = mid; } // 結果在區間[left, mid)
else if(nums[mid] == target){ return mid; }
else{ left = mid + 1; } // 結果在區間[mid + 1, right)
}
return -1;
}
}
class Solution {
public int search(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while(left <= right){ // 左閉右閉的版本,結果儲存在[left, right]中,只有left > right,意味著沒有找到結果
int mid = (left + right) / 2;
if(nums[mid] > target) { right = mid - 1; }
else if(nums[mid] == target){ return mid; }
else{ left = mid + 1; }
}
return -1;
}
}
34. 在排序陣列中查詢元素的第一個和最後一個位置
思想還是二分查詢,但分為兩個步驟,分別去找最左邊的和最右邊的。二分查詢我覺得還是先以一種方法去做吧,比如就只用左閉右閉的方式,這樣可以避免自己混亂。
class Solution {
public int[] searchRange(int[] nums, int target) {
return new int[] {findLeft(nums, target), findRight(nums, target)};
}
public int findLeft(int[] nums, int target){
int left = 0, right = nums.length - 1;
int ans = -1;
while(left <= right){
int mid = left + (right - left) / 2;
if(nums[mid] < target) { left = mid + 1; }
else if(nums[mid] == target) {
ans = mid;
right = mid - 1; // 找到target後,因為要找最左邊的,所以搜尋空間向左壓縮
}else{
right = mid - 1;
}
}
return ans;
}
public int findRight(int[] nums, int target){
int left = 0, right = nums.length - 1;
int ans = -1;
while(left <= right){
int mid = left + (right - left) / 2;
if(nums[mid] < target) { left = mid + 1; }
else if(nums[mid] == target) {
ans = mid;
left = mid + 1; // 同理,向右壓縮搜尋區間
}else{
right = mid - 1;
}
}
return ans;
}
}
27. 移除元素
我的直觀想法就是每遇見一個等於val的元素,就將其換到陣列的末尾,此時換過來的元素還沒有判斷,因此left不動,但換到結尾的元素一定要被刪除,因此right--;遇見不等於val的,不需要交換,left++即可;最終left會停止在陣列最後一個合法元素的下一個元素,其下標剛好為最終陣列的長度
class Solution {
public int removeElement(int[] nums, int val) {
int left = 0, right = nums.length - 1;
while(left <= right){
if(nums[left] == val){
nums[left] = nums[right];
nums[right] = val;
right -= 1;
} else{
left += 1;
}
}
return left;
}
}
今天這些題自己之前有做過,所以做起來還算得心應手,沒有完全忘掉。但還是一點,剛開始二分查詢就先記得用左閉右閉的方法去做,其實基本上大部分的題就套用模板,不要給自己增添別的負擔最好。