LeetCode第 75 場雙週賽題解
阿新 • • 發佈:2022-04-08
2220. 轉換數字的最少位翻轉次數
題目描述:給你兩個整數\(a , b\),每次可以翻轉a
的一個二進位制位,問最少需要多少次才可以將a
變成b
。
思路:顯然先將a , b
異或之後統計異或後的數字的二進位制位中1
的個數。
時間複雜度:\(O(logn)\)
參考程式碼:
class Solution { public: int minBitFlips(int start, int goal) { start ^= goal; int res = 0; for(int i = 30 ; i >= 0 ; --i) res += (start >> i) & 1; return res; } };
2221. 陣列的三角和
題目描述:給你一個長度為\(n - 1\)的陣列\(nums\),構造一個長度為\(n - 1\)的新陣列\(a\),滿足\(a_i = nums_i + nums_{i + 1} \forall 1 \leq i < n\)。若遞迴構造,直到新陣列的長度變為\(1\),問這個最終的陣列的值模10
後的值是多少。
思路:根據題意模擬即可
時間複雜度:\(O(n^2)\)
參考程式碼:
class Solution { public: int triangularSum(vector<int>& nums) { int res = 0, n = nums.size(); for(int i = n ; i >= 1 ; --i){ for(int j = 0 ; j < i ; ++j){ res += nums[j]; if(j < i - 1) nums[j] = (nums[j] + nums[j + 1]) % 10; } } return nums[0]; } };
6035. 選擇建築的方案數
題目描述:給你一個二進位制串,問你有多少長度為\(3\)的子串為101
或者010
。
思路:賽時思路參考了115. 不同的子序列
時間複雜度:\(O(n)\)
參考程式碼:
class Solution { public: long long numberOfWays(string s) { int n = s.size(); vector<vector<long long>> f(n + 1 , vector<long long>(4 , 0)); auto cal = [&](string t)->long long{ int n = s.size(), m = t.size(); for(int i = 0 ; i <= n ; ++i) f[i][0] = 1; for(int i = 1 ; i <= n ; ++i){ char c = s[i - 1]; for(int j = 1 ; j <= m ; ++j){ if(c == t[j - 1]) f[i][j] = f[i - 1][j] + f[i - 1][j - 1]; else f[i][j] = f[i - 1][j]; } } return f[n][m]; }; return cal("010") + cal("101"); } };
2223. 構造字串的總得分和
題目描述:給你一個長度為\(n\)的字串\(s\),對於它的每一個字尾,其得分為該字尾與原串的最長公共字首的長度,求\(s\)的得分。
思路:\(z\)函式的模板題目,注意\(z_0 = n\),具體證明可以看z函式(擴充套件KMP)。
時間複雜度:\(O(n)\)
參考程式碼:
class Solution {
private:
public:
long long sumScores(string s) {
int n = s.size();
vector<int>z(n, 0);
auto zFuncation = [&](int len) {
for (int i = 1, lr = 0, rs = 0; i < len; ++i) {
if (i <= rs && z[i - lr] < rs - i + 1) z[i] = z[i - lr];
else {
z[i] = max(0, rs - i + 1);
while (i + z[i] < len && s[z[i]] == s[i + z[i]]) ++z[i];
}
if (i + z[i] - 1 > rs) lr = i, rs = i + z[i] - 1;
}
return;
};
zFuncation(n);
long long res = 0;
for (auto& val : z) res += val;
res += n;
return res;
}
};