- 二分查找
- 移除元素
704題:二分查找
【思路】
有序數組按升序排序,如何找到目標值?
時間復雜度 O(logN),主要通過取中間點來節省遍歷的次數,重點在于邊界值的判斷,找到合適的那一半數據空間。
class Solution {
public int search(int[] nums, int target) {
// 條件里已為升序,不再單獨排序
// 確認數組左右邊界
int left = 0;
int right = nums.length - 1;
// 此處結束循環判斷使用下標
while(left <= right){
// 確認中間點,這邊right-left 為防止數字過大時的溢出情況
int mid = (right - left) / 2 + left ;
int num = nums[mid];
if(num == target){
return mid;
} else if(target > num){
// 目標值落在 右半段。移動篩選區間的左邊界,減少一半選擇范圍
left = mid + 1;
} else {
// 目標值落在 左半段。移動篩選區間的右邊界至中間居左
right = mid - 1;
}
}
// 表示異常
return -1;
}
}
27. 移除元素
【題目】
給你一個數組nums 和一個值 val,你需要 原地 移除所有數值等于 val 的元素,并返回移除后數組的新長度。
不要使用額外的數組空間,你必須僅使用 O(1) 額外空間并 原地 修改輸入數組。
元素的順序可以改變。你不需要考慮數組中超出新長度后面的元素。
【思路】
- 暴力解法(直接雙重for 移除數組元素,但是時間復雜度為 O(n^2))
public int removeElement(int[] nums, int val) {
int size = nums.length;
for(int i = 0; i < size; i++){
if(nums[i] == val){ // 發現需要移除的元素,就將數組集體向前移動一位
for(int j = i + 1; j < size; j++){
nums[j-1] = nums[j];
}
i--; // 因為下表i以后的數值都向前移動了一位,所以i也向前移動一位
size--; // 此時數組的大小-1
}
}
return size;
}
- 快慢指針 (一個快指針和慢指針在一個for 循環內完成兩個 for 循環的工作)
本題中,右指針指向當前將要處理的元素,左指針指向下一個將要賦值的位置。
public int removeElement(int[] nums, int val) {
int slowIndex = 0;
for(int fastIndex = 0; fastIndex < nums.length; fastIndex ++){
if(val != nums[fastIndex]){
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
return slowIndex;
}