一看就會,一作就廢😔java
5472. 從新排列字符串
給你一個字符串 s 和一個 長度相同 的整數數組 indices 。node
請你從新排列字符串 s ,其中第 i 個字符須要移動到 indices[i] 指示的位置。數組
返回從新排列後的字符串。this
示例 1: 輸入:s = "codeleet", indices = [4,5,6,7,0,2,1,3] 輸出:"leetcode" 解釋:如圖所示,"codeleet" 從新排列後變爲 "leetcode" 。
示例 2: 輸入:s = "abc", indices = [0,1,2] 輸出:"abc" 解釋:從新排列後,每一個字符都還留在原來的位置上。 示例 3: 輸入:s = "aiohn", indices = [3,1,4,2,0] 輸出:"nihao" 示例 4: 輸入:s = "aaiougrt", indices = [4,0,2,6,7,3,1,5] 輸出:"arigatou" 示例 5: 輸入:s = "art", indices = [1,0,2] 輸出:"rat"
提示:編碼
s.length == indices.length == n 1 <= n <= 100 s 僅包含小寫英文字母。 0 <= indices[i] < n indices 的全部的值都是惟一的(也就是說,indices 是整數 0 到 n - 1 造成的一組排列)。
class Solution { //新建一個數組,直接按照下標把當前的字符放進去 public String restoreString(String s, int[] indices) { char[] ss = s.toCharArray(); char[] res =new char[s.length()]; for(int i=0;i<s.length();i++){ res[indices[i]]=ss[i]; } return new String(res); } }
5473. 燈泡開關 IV (模擬遍歷)
房間中有 n 個燈泡,編號從 0 到 n-1 ,自左向右排成一行。最開始的時候,全部的燈泡都是 關 着的。spa
請你設法使得燈泡的開關狀態和 target 描述的狀態一致,其中 target[i] 等於 1 第 i 個燈泡是開着的,等於 0 意味着第 i 個燈是關着的。3d
有一個開關能夠用於翻轉燈泡的狀態,翻轉操做定義以下:rest
選擇當前配置下的任意一個燈泡(下標爲 i )
翻轉下標從 i 到 n-1 的每一個燈泡
翻轉時,若是燈泡的狀態爲 0 就變爲 1,爲 1 就變爲 0 。code
返回達成 target 描述的狀態所需的 最少 翻轉次數。圖片
示例 1: 輸入:target = "10111" 輸出:3 解釋:初始配置 "00000". 從第 3 個燈泡(下標爲 2)開始翻轉 "00000" -> "00111" 從第 1 個燈泡(下標爲 0)開始翻轉 "00111" -> "11000" 從第 2 個燈泡(下標爲 1)開始翻轉 "11000" -> "10111" 至少須要翻轉 3 次才能達成 target 描述的狀態 示例 2: 輸入:target = "101" 輸出:3 解釋:"000" -> "111" -> "100" -> "101". 示例 3: 輸入:target = "00000" 輸出:0 示例 4: 輸入:target = "001011101" 輸出:5
提示:
1 <= target.length <= 10^5 target[i] == '0' 或者 target[i] == '1'
class Solution { /* 按照從前向後開始模擬 若是當前位置的目標爲1看一下是否是開關燈的次數是否是偶數,若是是偶數,證實當前不能變成1,由於默認值都是0,因此要在改變一次 相反,當前位置爲0,看一下開關燈次數若是是奇數,那麼就要在改變一次 */ public int minFlips(String target) { char[] num = target.toCharArray(); int count = 0; for (char c : num){ if(c=='0' && count%2==1){ ++count; } else if(c=='1'&& count%2==0){ ++count; } } return count; } }
5474. 好葉子節點對的數量 (DFS搜索樹)
給你二叉樹的根節點 root 和一個整數 distance 。
若是二叉樹中兩個 葉 節點之間的 最短路徑長度 小於或者等於 distance ,那它們就能夠構成一組 好葉子節點對 。
返回樹中 好葉子節點對的數量 。
示例 1:
輸入:root = [1,2,3,null,4], distance = 3 輸出:1 解釋:樹的葉節點是 3 和 4 ,它們之間的最短路徑的長度是 3 。這是惟一的好葉子節點對。
示例 2:
輸入:root = [1,2,3,4,5,6,7], distance = 3 輸出:2 解釋:好葉子節點對爲 [4,5] 和 [6,7] ,最短路徑長度都是 2 。可是葉子節點對 [4,6] 不知足要求,由於它們之間的最短路徑長度爲 4 。
示例 3:
輸入:root = [7,1,4,6,null,5,3,null,null,null,null,null,2], distance = 3 輸出:1 解釋:惟一的好葉子節點對是 [2,5] 。
示例 4:
輸入:root = [100], distance = 1 輸出:0
示例 5:
輸入:root = [1,1,1], distance = 2 輸出:1
提示:
tree 的節點數在 [1, 2^10] 範圍內。 每一個節點的值都在 [1, 100] 之間。 1 <= distance <= 10
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { private int distance = 0; private int res = 0; public int countPairs(TreeNode root, int distance) { this.distance = distance; dfs(root); return res; } private int[] dfs(TreeNode node){ if(node == null){ return new int[distance + 1]; } int[] dis = new int[distance + 1]; if(node.left == null && node.right == null){ dis[1] = 1; return dis; } //左右的數量 int[] left = dfs(node.left); int[] right = dfs(node.right); for(int i = 1; i < distance; i++){ //這裏left是左面,right的是要減去左面的的步數的因此範圍要-i for(int j = 1; j <= distance - i; j++){ //左右相乘就是方案數 res += left[i] * right[j]; } } //dis是第幾個的位置,就是left,right上一位的 //dis[2]二點的位置,要一點位置的左右兩個 //就是dis【i】就表明,距離爲i的數量 for(int i = 2; i <= distance; i++){ dis[i] = left[i - 1] + right[i - 1]; } return dis; } }
5462. 壓縮字符串 II (DFS搜索)
行程長度編碼 是一種經常使用的字符串壓縮方法,它將連續的相同字符(重複 2 次或更屢次)替換爲字符和表示字符計數的數字(行程長度)。例如,用此方法壓縮字符串 「aabccc」 ,將 「aa」 替換爲 「a2」 ,「ccc」 替換爲` 「c3」 。所以壓縮後的字符串變爲 「a2bc3」 。
注意,本問題中,壓縮時沒有在單個字符後附加計數 ‘1’ 。
給你一個字符串 s 和一個整數 k 。你須要從字符串 s 中刪除最多 k 個字符,以使 s 的行程長度編碼長度最小。
請你返回刪除最多 k 個字符後,s 行程長度編碼的最小長度 。
示例 1:
輸入:s = "aaabcccd", k = 2 輸出:4 解釋:在不刪除任何內容的狀況下,壓縮後的字符串是 "a3bc3d" ,長度爲 6 。最優的方案是刪除 'b' 和 'd',這樣一來,壓縮後的字符串爲 "a3c3" ,長度是 4 。
示例 2:
輸入:s = "aabbaa", k = 2 輸出:2 解釋:若是刪去兩個 'b' 字符,那麼壓縮後的字符串是長度爲 2 的 "a4" 。
示例 3:
輸入:s = "aaaaaaaaaaa", k = 0 輸出:3 解釋:因爲 k 等於 0 ,不能刪去任何字符。壓縮後的字符串是 "a11" ,長度爲 3 。
提示:
1 <= s.length <= 100 0 <= k <= s.length s 僅包含小寫英文字母
class Solution { public int getLengthOfOptimalCompression(String s, int k) { int n = s.length(); Integer[][][][] dp = new Integer[n + 1][26][n + 1][k + 1]; return dfs(dp, s, 0, s.charAt(0), 0, k); } //題目字符串 當前位置 當前位置的字符 當前字符前面有多少相同的 剩餘可刪除的字符 private int dfs(Integer[][][][] dp, String s, int cur, char c, int num, int k){ int n = s.length(); if(cur >= n){ //最後一位若是是一位的字母或者小於1位,就用這個數,若是是多個數字,大於等於10就是兩位,小於10就是一位 return num <= 1 ? num: 1 + (num >= 10 ? 2: 1); } //若是當前這一位計算過,那麼就能夠直接返回了,剪枝 if(dp[cur][c - 'a'][num][k] != null){ return dp[cur][c - 'a'][num][k]; } //若是和上一位不同 if(s.charAt(cur) != c){ //看看前面的那個數字有多少相同的,而後加上後面便利的 dp[cur][c - 'a'][num][k] = (num <= 1 ? num: 1 + (num >= 10 ? 2: 1)) + dfs(dp, s, cur + 1, s.charAt(cur), 1, k); } else { //若是相等,繼續日後面擴展 dp[cur][c - 'a'][num][k] = dfs(dp, s, cur + 1, c, num + 1, k); } if(k > 0){ //若是還能減的話,就嘗試一下吧當前的這個剪掉 dp[cur][c - 'a'][num][k] = Math.min(dp[cur][c - 'a'][num][k], dfs(dp, s, cur + 1, c, num, k - 1)); } //返回 return dp[cur][c - 'a'][num][k]; } }