此次我只作對一題。html
緣由是題目返回值類型有誤,寫的是 String[]
,實際上應該返回 List<String>
。java
好吧,只能自認倒黴。就當漲漲經驗。web
大體思路是用兩層循環檢查每兩個短語是否能先後拼接成新短語。若是能夠先後拼接,那麼將它們拼接成新短語,並添加到結果列表。最後將列表升序返回。數組
因爲須要第一個單詞和最後一個單詞,所以須要先進行分割處理,將獲得的第一個單詞和最後一個單詞分別保存。因爲能夠肯定大小,所以直接用二維數組保存便可。app
// ht[i][0]表示第i個短語的第一個單詞,ht[i][1]表示第i個短語的最後一個單詞 String[][] ht = new String[phrases.length][2]
一、短語 1 和短語 2,一種是 1 在前,2 在後,另外一種是 2 在前,1 在後。
二、短語不能和本身先後拼接。
三、結果列表中的新短語不能重複,if
判斷便可。ssh
坑:返回值改成 List<String>
。ide
時間複雜度:雙重 for
循環,故時間複雜度爲 O(n2)。
空間複雜度:一個二維數組,一個列表,都和 n
有關,兩個字符串 s
。故空間複雜度爲 O(n)。svg
class Solution { // 方法的返回值要改成List<String>,不然會報錯 public List<String> beforeAndAfterPuzzles(String[] phrases) { // 短語的第一個單詞和最後一個單詞 String[][] ht = new String[phrases.length][2]; // 分割短語,並獲取第一個單詞和最後一個單詞 for (int i = 0; i < phrases.length; ++i) { String[] phrase = phrases[i].split(" "); ht[i][0] = phrase[0]; ht[i][1] = phrase[phrase.length - 1]; } List<String> ans = new ArrayList<>();// 結果 for (int i = 0; i < phrases.length; ++i) { for (int j = i + 1; j < phrases.length; ++j) { // 短語i的最後一個單詞和短語j的第一個單詞相同 if (ht[i][1].equals(ht[j][0])) { String s = phrases[i]; s += phrases[j].replaceFirst(ht[j][0], ""); if (!ans.contains(s)) {// 確保新短語不重複 ans.add(s); } } // 短語j的最後一個單詞和短語i的第一個單詞相同 if (ht[j][1].equals(ht[i][0])) { String s = phrases[j]; s += phrases[i].replaceFirst(ht[i][0], ""); if (!ans.contains(s)) { ans.add(s); } } } } Collections.sort(ans);// 升序 return ans; } }
基本思路:
將三種顏色的下標分開保存,每種顏色的個數未知,採用 List
,比較方便。
查詢顏色 c
的列表中是否有下標 i
,若是有,說明距離爲 0,若是沒有,就獲取最近的距離。spa
查詢部分:code
c
的列表爲空,說明沒有這種顏色,所以將 -1 添加到結果中。c
的列表不爲空,說明有這種顏色。
i
的左邊沒有這種顏色,col.get(posR) - i
即爲最近的距離。i
右邊沒有這種顏色,i - col.get(posL)
即爲最近的距離。時間複雜度:查詢的循環裏面有個二分查找,所以最壞的狀況下,時間複雜度爲
。
空間複雜度:兩個鏈表,所以爲
。
class Solution { // 返回值改成List<Integer>,不然編譯出錯 public List<Integer> shortestDistanceColor( int[] colors, int[][] queries) { List<List<Integer>> color = new ArrayList<>();// 顏色1,2,3的列表 for (int i = 0; i < 4; ++i) { color.add(new ArrayList<>()); } for (int i = 0; i < colors.length; ++i) { color.get(colors[i]).add(i);// 將每種顏色的索引保存到對應的顏色列表 } List<Integer> ans = new ArrayList<>();// 結果 for (int[] querie : queries) { int i = querie[0];// 索引 int c = querie[1];// 顏色 List<Integer> col = color.get(c);// 顏色c的列表 if (col.isEmpty()) {// 沒有這種顏色 ans.add(-1);// 不存在解決方案,添加-1 continue;// 繼續下一個查詢 } // 在顏色c的列表中查找值爲i的索引 int pos = Collections.binarySearch(col, i); if (pos >= 0) {// 找到 ans.add(0);// 說明距離索引i最近的顏色c就是它本身(距離爲0) continue; } // 未找到,pos表示第一個大於i的值的索引減1 int posR = -pos - 1;// 第一個大於i的值的索引,範圍是[0,col.size()] int posL = posR - 1;// 第一個小於i的值的索引 if (posR == 0) {// 顏色c的全部索引都比i大,即索引i的左邊沒有顏色c ans.add(col.get(0) - i);// 最近的距離 continue; } if (posR == col.size()) {// 顏色c的全部索引都比i小,即索引i的右邊沒有顏色c ans.add(i - col.get(posL));// 最近的距離 continue; } // 索引i的左右都有顏色c,取最近的距離 ans.add(Math.min(i - col.get(posL), col.get(posR) - i)); } return ans; } }
參考https://leetcode.com/savevmk的代碼。
暫時還沒弄懂爲何能夠這樣作。感受這個方法太巧妙了。
class Solution { public int maximumNumberOfOnes( int width, int height, int sideLength, int maxOnes) { int[] arr = new int[sideLength * sideLength];// 子陣的一維形式 for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { int row = i % sideLength; int col = j % sideLength; ++arr[row * sideLength + col]; } } Arrays.sort(arr);// 升序 int ans = 0;// 結果 for (int i = 0; i < maxOnes; ++i) { ans += arr[arr.length - 1 - i];// 1的數量 } return ans; } }