此次我只作对一题。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; } }