leetcode刷題總結801-850
801. 使序列遞增的最小交換次數
描述:
思路:
class Solution { public: int minSwap(vector<int>& A, vector<int>& B) { int res = 0; vector<vector<int>> dp(A.size(),vector(2,0)); dp[0][0] = 0; dp[0][1] = 1; for(int i = 1;i < A.size();i++) {if(A[i-1]<A[i]&&B[i-1]<B[i]){ if(A[i-1]<B[i] && B[i-1]<A[i]){//任意交換或者不交換,取最優值 dp[i][0] = min(dp[i-1][0],dp[i-1][1]); dp[i][1] = min(dp[i-1][0],dp[i-1][1])+1; }else{ dp[i][0] = dp[i-1][0];//不交換,則上個位置也不能交換 dp[i][1] = dp[i-1][1]+1; //交換,則上個位置也必須交換 } }else{ dp[i][0] = dp[i-1][1];// 不交換,則上個位置必須交換 dp[i][1] = dp[i-1][0]+1;// 交換,則上個位置不能交換 } } return min(dp[A.size()-1][0],dp[A.size()-1][1]); } };
807. 保持城市天際線
描述:
思路:先對 從上到下,從左到右統計。統計完後對每個座標進行 可以增添高度的 統計。
808. 分湯
描述:
思路:
轉移方程:dp[i][j] = 0.25 * (dp[i-100][j] + dp[i-75][j-25] + dp[i-50][j-50] + dp[i-75][j-25])
將N縮小為原來的25分之一的轉移方程:dp[i][j] = 0.25 * (dp[i-4][j] + dp[i-3][j-1] + dp[i-2][j-2] + dp[i-3][j-1])
809. 情感豐富的文字
描述:
思路:
我們首先將 S 拆分成若干組相同的字母,並存儲每組字母的長度。例如當 S 為 abbcccddddaaaaa 時,可以得到 5 組字母,它們分別為 abcda,長度為 [1, 2, 3, 4, 5]。
對於 words 中的每個單詞 word,如果它可以擴張得到 S,那麼它必須和 S 有相同的字母組。對於每一組字母,假設 S 中有 c1 個,word 中有 c2 個,那麼會有下面幾種情況:
如果 c1 < c2,那麼 word 不能擴張得到 S;
如果 c1 >= 3,那麼只要新增 c1 - c2 個字母即可;
如果 c1 < 3,由於在擴張時至少需要新增到 3 個字母,所以此時不能新增字母,必須有 c1 == c2。
如果 word 的包含的字母組中的每個字母都滿足上述情況,那麼 word 可以擴張得到 S。
813. 最大平均值和的分組
描述:
思路:
dp(i, k) = max(dp(j, k - 1) + average(j + 1, i))
dp(i, 0) = average(0, i)
814. 二叉樹剪枝
描述:
思路:
class Solution { public TreeNode pruneTree(TreeNode root) { return containsOne(root) ? root : null; } public boolean containsOne(TreeNode node) { if (node == null) return false; boolean a1 = containsOne(node.left); boolean a2 = containsOne(node.right); if (!a1) node.left = null; if (!a2) node.right = null; return node.val == 1 || a1 || a2; } }
815. 公交路線
描述:
思路:廣度優先。。。看到最少 最低 首先想到 廣度。
817. 連結串列元件
描述:
思路:線性掃描即可。
820. 單詞的壓縮編碼
描述:
思路:先set。然後對set去除所有substring(i,length)的字元。然後再計算+1.
825. 適齡的朋友
描述:
思路:
class Solution { public int numFriendRequests(int[] ages) { int[] count = new int[121]; for (int age: ages) count[age]++; int ans = 0; for (int ageA = 0; ageA <= 120; ageA++) { int countA = count[ageA]; for (int ageB = 0; ageB <= 120; ageB++) { int countB = count[ageB]; if (ageA * 0.5 + 7 >= ageB) continue; if (ageA < ageB) continue; if (ageA < 100 && 100 < ageB) continue; ans += countA * countB; if (ageA == ageB) ans -= countA; } } return ans; } }View Code
829. 連續整數求和
描述:
思路:
class Solution { public int consecutiveNumbersSum(int N) { int ans = 0; for (int start = 1; start <= N; ++start) { int target = N, x = start; while (target > 0) target -= x++; if (target == 0) ans++; } return ans; } }
836. 矩形重疊
描述:
思路:
class Solution {
public boolean isRectangleOverlap(int[] rec1, int[] rec2) {
return !(rec1[2] <= rec2[0] || // left
rec1[3] <= rec2[1] || // bottom
rec1[0] >= rec2[2] || // right
rec1[1] >= rec2[3]); // top
}
}
837. 新21點
描述:
思路:
838. 推多米諾
描述:
思路: