這次我只做對一題。
原因是題目返回值類型有誤,寫的是 String[]
,實際上應該返回 List<String>
。
好吧,只能自認倒霉。就當漲漲經驗。
5068. 前后拼接
解題思路
大致思路是用兩層循環檢查每兩個短語是否能前后拼接成新短語。如果可以前后拼接,那么將它們拼接成新短語,並添加到結果列表。最后將列表升序返回。
由於需要第一個單詞和最后一個單詞,因此需要先進行分割處理,將得到的第一個單詞和最后一個單詞分別保存。由於可以確定大小,因此直接用二維數組保存即可。
// ht[i][0]表示第i個短語的第一個單詞,ht[i][1]表示第i個短語的最后一個單詞
String[][] ht = new String[phrases.length][2]
1、短語 1 和短語 2,一種是 1 在前,2 在后,另一種是 2 在前,1 在后。
2、短語不能和自己前后拼接。
3、結果列表中的新短語不能重復,if
判斷即可。
坑:返回值改為 List<String>
。
時間復雜度:雙重 for
循環,故時間復雜度為 O(n2)。
空間復雜度:一個二維數組,一個列表,都和 n
有關,兩個字符串 s
。故空間復雜度為 O(n)。
Java代碼
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;
}
}
提交結果
5070. 與目標顏色間的最短距離
解題思路
基本思路:
將三種顏色的下標分開保存,每種顏色的個數未知,采用 List
,比較方便。
查詢顏色 c
的列表中是否有下標 i
,如果有,說明距離為 0,如果沒有,就獲取最近的距離。
查詢部分:
- 如果顏色
c
的列表為空,說明沒有這種顏色,因此將 -1 添加到結果中。 - 如果顏色
c
的列表不為空,說明有這種顏色。- 如果索引
i
的左邊沒有這種顏色,col.get(posR) - i
即為最近的距離。 - 如果索引
i
右邊沒有這種顏色,i - col.get(posL)
即為最近的距離。 - 如果兩邊都有這種顏色,取上面兩個式子的最小值即為最近的距離。
- 如果索引
時間復雜度:查詢的循環里面有個二分查找,因此最壞的情況下,時間復雜度為
。
空間復雜度:兩個鏈表,因此為
。
Java代碼
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;
}
}
提交結果
1183. 矩陣中 1 的最大數量
解題思路
參考https://leetcode.com/savevmk的代碼。
暫時還沒弄懂為什么可以這樣做。感覺這個方法太巧妙了。
Java代碼
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;
}
}