704. 二分查詢
題目連結:https://leetcode.cn/problems/binary-search/
題目難度:簡單
文章講解:https://programmercarl.com/0704.二分查詢.html
影片講解: https://www.bilibili.com/video/BV1fA4y1o715
題目狀態:透過
個人思路:
就是簡單的二分查詢思路,判斷陣列中間的值是否等於目標值,不等於就更新範圍。
具體程式碼:
class Solution {
public:
int search(vector<int>& nums, int target) {
int low = 0, high = nums.size() - 1;
return Binary(nums, low, high, target);
}
int Binary(vector<int> &nums, int low, int high, int target) {
if(low > high) return -1;
int mid = low + (high - low) / 2;
if(nums[mid] == target) {
return mid;
}
else if(nums[mid] > target) {
return Binary(nums, low, mid - 1, target);
}
else {
return Binary(nums, mid + 1, high, target);
}
}
};
27. 移除元素
題目連結:https://leetcode.cn/problems/remove-element/
題目難度:簡單
文章講解:https://programmercarl.com/0027.移除元素.html
影片講解: https://www.bilibili.com/video/BV12A4y1Z7LP
題目狀態:透過
個人思路:
一開始要打算直接用erase
函式的,但是感覺這應該不是考察的重點,然後就使用了雙指標。
- 當左邊指標
i
對應的值等於要刪除的元素時,將位於右邊的指標j
的值覆蓋到左邊指標,並且j++
; - 當左邊指標
i
對應的值不等於要刪除的元素時,i++
。
具體程式碼:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int i = 0, j = nums.size();
while(i < j) {
if(nums[i] == val) {
nums[i] = nums[j - 1];
j--;
}
else {
i++;
}
}
return j;
}
};
卡哥思路我還真沒想過,使用快慢指標
實現程式碼:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int n = nums.size();
int i = 0;
for(int j = 0; j < n; ++j) {
if(val != nums[j]) {
nums[i] = nums[j];
i++;
}
}
return i;
}
};
26. 刪除有序陣列中的重複項
題目連結:https://leetcode.cn/problems/remove-duplicates-from-sorted-array/
題目難度:簡單
題目狀態:透過
個人思路:
學習卡哥上題的思路,使用快慢指標
具體程式碼:
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int slow = 0;
for(int fast = 1; fast < nums.size(); ++fast) {
if(nums[slow] != nums[fast]) {
slow++;
nums[slow] = nums[fast];
}
}
return slow + 1;
}
};
283. 移動零
題目連結:https://leetcode.cn/problems/move-zeroes/
題目難度:簡單
題目狀態:透過
個人思路:
快慢指標太好用了,一次過。
- 使用快指標遍歷;
- 當慢指標的值為0,且快指標的值不為0時,快慢指標對應的值交換;
- 當慢指標的值不為0時,將慢指標移動到下一個。
具體程式碼:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int i = 0;
for(int j = 0; j < nums.size(); ++j) {
if(nums[i] == 0 && nums[j] != 0) {
swap(nums[i], nums[j]);
}
if(nums[i] != 0) i++;
}
}
};
844. 比較含退格的字串
題目連結:https://leetcode.cn/problems/backspace-string-compare/
題目難度:簡單
題目狀態:沒有思路,看題解
當我感覺自己會使用雙指標的時候,想法破裂了……
力扣官方題解
1. 棧
當判斷一個陣列中的元素不為#
時,將該元素入棧;而該元素為#
且棧不為空時,出棧。最終判斷兩個字串的棧是否相同。
實現程式碼如下:
class Solution {
public:
bool backspaceCompare(string s, string t) {
return build(s) == build(t);
}
string build(string s) {
string res;
for(auto i : s) {
if(i != '#') {
res.push_back(i);
}
else if(!res.empty()) {
res.pop_back();
}
}
return res;
}
};
2. 雙指標法
先看圖解(來自力扣官方):
一個字元是否會被刪掉,只取決於該字元後面的退格符,而與該字元前面的退格符無關。因此當我們逆序地遍歷字串,就可以立即確定當前字元是否會被刪掉。
具體地,我們定義 skip
表示當前待刪除的字元的數量。每次我們遍歷到一個字元:
-
若該字元為退格符,則我們需要多刪除一個普通字元,我們讓
skip
加 1; -
若該字元為普通字元:
- 若
skip
為 0,則說明當前字元不需要刪去; - 若
skip
不為 0,則說明當前字元需要刪去,我們讓skip
減 1。
- 若
這樣,我們定義兩個指標,分別指向兩字串的末尾。每次我們讓兩指標逆序地遍歷兩字串,直到兩字串能夠各自確定一個字元,然後將這兩個字元進行比較。重複這一過程直到找到的兩個字元不相等,或遍歷完字串為止。
class Solution {
public:
bool backspaceCompare(string S, string T) {
int i = S.length() - 1, j = T.length() - 1;
int skipS = 0, skipT = 0;
while (i >= 0 || j >= 0) {
while (i >= 0) {
if (S[i] == '#') {
skipS++, i--;
} else if (skipS > 0) {
skipS--, i--;
} else {
break;
}
}
while (j >= 0) {
if (T[j] == '#') {
skipT++, j--;
} else if (skipT > 0) {
skipT--, j--;
} else {
break;
}
}
if (i >= 0 && j >= 0) {
if (S[i] != T[j]) {
return false;
}
} else {
if (i >= 0 || j >= 0) {
return false;
}
}
i--, j--;
}
return true;
}
};
977. 有序陣列的平方
題目連結:https://leetcode.cn/problems/squares-of-a-sorted-array/
題目難度:簡單
題目狀態:之前做過,且已透過
個人思路:
建立一個新陣列res
,用來儲存結果。
使用雙指標分別指向有序陣列的兩端,並建立一個指標指向res
的尾部。
判斷雙指標所指的值的平方哪個更大,並將更大的值存入res
。
實現程式碼:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int n = nums.size();
vector<int> res(n);
int i = 0, j = n - 1, k = n - 1;
while(i <= j)
{
if(nums[i] * nums[i] > nums[j] * nums[j])
{
res[k] = nums[i] * nums[i];
i++;
}
else
{
res[k] = nums[j] * nums[j];
j--;
}
k--;
}
return res;
}
};