1. 程式人生 > 其它 >LeetCode第 75 場雙週賽題解

LeetCode第 75 場雙週賽題解

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;
	}
};