LeetCode #160 周賽
leetcode 題目不同於其他 oj 是黑盒測試,要提交完整可運行代碼,而是完善封裝好題目給出的函數即可
1237、找出給定方程的正整數解
題目:給出函數 ,和整數 。求所有滿足 的 。
分析:由於 範圍 ,直接暴力枚舉。
class Solution {
public:
vector<vector<int>> findSolution(CustomFunction& customfunction, int z) {
vector<vector<int>> v;
for (int i = 1; i <= 1e3; i++) {
for (int j = 1; j <= 1e3; j++) {
if (customfunction.f(i, j) == z) {
v.push_back({i, j});
}
}
}
return v;
}
};
1238、循環碼排列
題目: 給出 ,要求輸出以 開頭的 的排列,且排列要滿足相鄰兩數的二進制表示相差一位。
分析:格雷碼(循環二進制單位距離碼)是任意兩個相鄰數的代碼只有一位二進制數不同的編碼,。
①、通過模擬(上下鏡射加新位):
class Solution {
public:
vector<int> circularPermutation(int n, int start) {
vector<int> v = {0, 1}, res;
for (int i = 2; i <= n; i++) {
for (int j = v.size() - 1; j >= 0; j--) {
v.push_back(v[j] + (1 << (i-1)));
}
}
int pos = find(v.begin(), v.end(), start) - v.begin();
int m = v.size();
while (m--) {
res.push_back(v[pos]); pos = (pos + 1) % v.size();
}
return res;
}
};
②、通過分析二進制表示:
class Solution {
public:
vector<int> circularPermutation(int n, int start) {
vector<int> v, res;
int pos;
for (int i = 0; i < 1 << n; i++) {
v.push_back(i ^ (i >> 1));
if (v.back() == start) pos = i;
}
int m = v.size();
while (m--) {
res.push_back(v[pos]); pos = (pos + 1) % v.size();
}
return res;
}
};
1239、串聯字符串的最大長度
題目:給一個字符串數組 ,選擇數組 的子序列組成新的字符串 ,但 種不能有重複字符,求 最大長度。
分析:暴力 每一位選或者不選,不過要加上剪枝:對於每一位,只有加上後沒有重複字符纔會繼續。
class Solution {
public:
int dfs(vector<string>& arr, string str, int pos, int* vis) {
if (pos == arr.size()) return str.size();
int ans = dfs(arr, str, pos + 1, vis); // 不選當前位置
int tmp[30];
for (int i = 0; i < 30; i++) tmp[i] = vis[i]; // 遞歸時會改變指針,所以要備份
for (auto x : arr[pos]) { // 選當前位置,但不能有重複
if (tmp[x - 'a'] == 1) return ans;
else tmp[x - 'a'] = 1;
}
return max(dfs(arr, str + arr[pos], pos + 1, tmp), ans); // 取最大
}
int maxLength(vector<string>& arr) {
int vis[30] = {0};
return dfs(arr, "", 0, vis);
}
};
1240、鋪瓷磚
題目:給你 矩陣,讓你分割成若干正方形,求最小分割數。
分析:矩陣最小正方形剖分