📘 題目敘述
給定兩個字串 s1 和 s2,它們的長度都剛好是 4,並且只包含小寫英文字母。
你可以對其中任一個字串做任意次以下操作:
- 選兩個索引
i和j - 滿足
j - i = 2 - 然後交換這兩個位置的字元
請判斷是否可以透過這些操作,讓 s1 和 s2 變成一樣。
如果可以,回傳 true;否則回傳 false。
條件限制
s1.length == s2.length == 4s1和s2只包含小寫英文字母
🧠 解題思路
我這題的想法就是直接把所有可能情況列出來。
因為字串長度固定只有 4,而且能交換的位置也固定只有:
0和21和3
所以本質上可以調動的只有兩組:
- 偶數位置那一組:
0、2 - 奇數位置那一組:
1、3
也就是說,我只要檢查:
s1的第0、2個字元,能不能對上s2的第0、2個字元- 同時
s1的第1、3個字元,能不能對上s2的第1、3個字元
因為每組都只有兩個位置,所以每組其實就只有「不換」或「交換」兩種可能。 這樣直接把所有組合情況列出來判斷就可以了。
所有變數
這題不需要😄
🪜 主要流程步驟
1. 先檢查兩個字串本來是不是就一樣
我一開始先判斷:
if (s1 == s2) {
return true;
}
如果兩個字串本來就完全相同,那就不需要做任何操作,直接回傳 true。
2. 先處理偶數位置 0 和 2 不交換的情況
因為題目允許交換的只有距離為 2 的位置,所以對長度 4 的字串來說,偶數位置只會是 0 和 2 互換。
我先檢查 s1[0] 和 s1[2] 是否剛好可以對上 s2[0] 和 s2[2],也就是:
if (s1[0] == s2[0] && s1[2] == s2[2]) {
這代表偶數位置這一組不用交換,就已經對上了。
在這種情況下,我再去看奇數位置 1 和 3 有沒有辦法對上。
3. 在偶數位置固定的情況下,再檢查奇數位置的兩種可能
當偶數位置已經對上之後,奇數位置 1 和 3 只剩兩種可能:
- 不交換:
s1[1] == s2[1]且s1[3] == s2[3] - 交換:
s1[1] == s2[3]且s1[3] == s2[1]
所以我就直接把這兩種情況都列出來。
只要其中一種成立,就表示可以透過合法操作把字串變成一樣,直接回傳 true。
4. 再處理偶數位置 0 和 2 交換的情況
如果前面那種情況不成立,我就再檢查另一種可能,也就是偶數位置其實需要交換:
if (s1[0] == s2[2] && s1[2] == s2[0]) {
這代表 s1 的第 0 和第 2 個字元,要互換之後才會和 s2 的偶數位置對上。
接著和前面一樣,我再去檢查奇數位置是不是:
- 不交換就能對上
- 或交換後能對上
只要成立其中一種,就回傳 true。
5. 如果所有情況都不成立,就回傳 false
如果前面列出的所有可能都不符合,
就代表即使把 (0, 2) 和 (1, 3) 的交換情況全部試過,還是沒辦法讓 s1 變成 s2。
那最後就只能回傳:
return false;
⏱️ 複雜度
- 時間複雜度:
O(1)因為字串長度固定是4,我只是在檢查固定數量的情況。 - 空間複雜度:
O(1)只用了固定數量的額外空間。
💻 程式碼實作
class Solution {
public:
bool canBeEqual(string s1, string s2) {
if (s1 == s2) {
return true;
}
if (s1[0] == s2[0] && s1[2] == s2[2]) {
if (s1[1] == s2[1] && s1[3] == s2[3]) {
return true;
}
if (s1[1] == s2[3] && s1[3] == s2[1]) {
return true;
}
}
if (s1[0] == s2[2] && s1[2] == s2[0]) {
if (s1[1] == s2[1] && s1[3] == s2[3]) {
return true;
}
if (s1[1] == s2[3] && s1[3] == s2[1]) {
return true;
}
}
return false;
}
};
🔗 題目連結
https://leetcode.com/problems/check-if-strings-can-be-made-equal-with-operations-i/