LeetCode #161 場周賽
(感覺 LeetCode 上的題不需要考慮複雜度,能想出來做法就能過
5247. 交換字符使得字符串相同
題目:給你兩個只包含 ‘x’, ‘y’ 的字符串 ,每次操作可以交換兩個分別位於兩個字符串中的字符,問最少交換幾次可以使字符串變爲完全相同。
分析:首先兩個字符串 ‘x’,‘y’ 總數不是偶數,都是不行的。
只關心字符串不相同的位置,(x -> y) 或者 (y -> x)。統計兩者個數 。兩個 (x -> y) 可以用一次操作消除,(y -> x)同理。
class Solution {
public:
int minimumSwap(string s1, string s2) {
map<char, int> mp;
int s1Size = s1.size();
int ans1 = 0, ans2 = 0;
for (int i = 0; i < s1Size; i++) {
if (s1[i] != s2[i]) {
if (s1[i] == 'x') ans1++;
else ans2++;
}
mp[s1[i]]++; mp[s2[i]]++;
}
if ((mp['x'] & 1) || (mp['y'] & 1)) return -1;
return ans1 / 2 + ans2 / 2 + (ans1 % 2 + ans2 % 2);
}
};
5248. 統計「優美子數組」
題目:給一個數組 和 。問奇數個數爲 的子數組有多少。
分析:考慮找到了一個元區間 ,剛好奇數個數爲 ,且端點都是奇數。統計兩端各有多少 0,(分別用 x, y 表示)。那麼對於這個區間能構成的子數組數量爲
2 2 2 1 2 1 2 2 2
2
對於 1 2 1 元區間,,則 。
遍歷所有元區間即可加和即可。
class Solution {
public:
int numberOfSubarrays(vector<int>& nums, int k) {
int ans = 0, n = nums.size();
int pos[50010], cnt = 0;
for (int i = 0; i < n; i++) { // 記錄奇數位置的下標
if (nums[i] & 1) pos[cnt++] = i;
}
if (cnt < k) return 0;
int i = 0, j = k - 1;
int L = -1; pos[cnt] = n; // 加上邊界
while (j < cnt) {
int x = pos[i] - L - 1;
int y = pos[j + 1] - pos[j] - 1;
L = pos[i];
i++; j++;
ans += (x * y + x + y + 1);
}
return ans;
}
};
大神做法:
首先 是 中的函數,返回一個區間的左右端點,分別代表 。
預處理奇數數量的前綴和。之後對於每一位直接求滿足條件的區間長度即可。
class Solution {
public:
int numberOfSubarrays(vector<int>& a, int k) {
int n = a.size();
vector<int> s(n+1);
for (int i = 1; i <= n; ++ i)
s[i] = s[i-1]+a[i-1]%2;
int ret = 0;
for (int i = 0; i < n; ++ i)
{
auto p = equal_range(s.begin(), s.end(), s[i]+k);
ret += p.second-p.first;
}
return ret;
}
};
5249. 移除無效的括號
題目:給字符串 s(由括號,小寫字母組成),返回有效字符串(括號相對應)。
分析:用棧匹配括號,刪去無效括號即可。
class Solution {
public:
string minRemoveToMakeValid(string s) {
stack<int> st; string ans;
vector<int> pos(s.size(), 1);
for (int i = 0; i < s.size(); i++) {
if (s[i] == '(') st.push(i);
else if (s[i] == ')') {
if (st.empty()) pos[i]--;
else st.pop();
}
}
while (!st.empty()) {
pos[st.top()]--; st.pop();
}
for (int i = 0; i < s.size(); i++) if (pos[i]) ans += s[i];
return ans;
}
};
5250. 檢查「好數組」
題目:
分析:裴蜀定理:
要使 有解,
求所有數最大公約數是否等於 1 即可。
class Solution {
public:
bool isGoodArray(vector<int>& a) {
int n = a.size();
int ret = a[0];
for (auto x : a) ret = __gcd(ret, x);
return ret == 1;
}
};