leetcode 57 Insert Interval & leetcode 1046 Last Stone Weight & leetcode 1047 Remove All Adjacent Duplicates in String & leetcode 56 Merge Interval
lc57 Insert Interval 仔细分析题目,发现我们只需要处理那些与插入interval重叠的interval即可,换句话说,那些end早于插入start以及start晚于插入end的interval都可以保留。我们只需要两个指针,i&j分别保存重叠interval中最早start和最晚end即可,然后将interval [i, j]插入即可
1 class Solution { 2 public int[][] insert(int[][] intervals, int[] newInterval) { 3 List<int[]> res = new ArrayList<>(); 4 5 for(int[] interval : intervals){ 6 if(interval[1] < newInterval[0]){ 7 res.add(interval); 8 } 9 else if(interval[0] > newInterval[1]){ 10 res.add(newInterval); 11 newInterval = interval; 12 } 13 else{ 14 newInterval[0] = Math.min(newInterval[0], interval[0]); 15 newInterval[1] = Math.max(newInterval[1], interval[1]); 16 } 17 } 18 res.add(newInterval); 19 return res.toArray(new int[0][0]); 20 21 } 22 }
lc1046 Last Stone Weight 用优先队列解,弹出两个最大值,比较他们的差值,然后按题目描述操作即可。
注意java自带的PriorityQueue是自然顺序,别忘了改成降序, PriorityQueue<Integer> pq = new PriorityQueue<>(Comparator.reverseOrder());
1 class Solution { 2 public int lastStoneWeight(int[] stones) { 3 PriorityQueue<Integer> pq = new PriorityQueue<>(Comparator.reverseOrder()); 4 5 for(int stone :stones){ 6 pq.offer(stone); 7 } 8 9 while(pq.size() > 1){ 10 int max1 = pq.poll(); 11 int max2 = pq.poll(); 12 13 if(max1 != max2) 14 pq.offer(max1 - max2); 15 } 16 return pq.size() > 0 ? pq.peek() : 0; 17 18 } 19 }
lc1047 Remove All Adjacent Duplicates in String
1)用stack,创建一个与原数组(题目输入为String S,访问某一index时别忘了用charAt(),或者直接新建一个char数组,用S.toChar()把S转成char[])同样大小的数组,两个index,i&j,i用来遍历原数组,j用来处理stack。判断栈顶元素是否与当前i指向元素相等,相等就j--,否则就给stack[j]赋值为SChar[i]并继续loop
2)双指针,一个正常遍历原数组的索引i,另一个模拟stack操作,但是不需要额外申请空间,直接指向原数组的指针j。注意初值要设成-1,否则不方便初始化。其它逻辑同1)。返回值就是原数组的0-i。所以要注意长度应该设成i+1,new String(Schar, 0, i+1)
给出双指针版代码
1 class Solution { 2 public String removeDuplicates(String S) { 3 int len = S.length(); 4 char[] tmp = new char[len]; 5 6 int i=0; 7 for(int j=0; j<len; j++){ 8 if(i>0 && tmp[i-1] == S.charAt(j)) 9 i--; 10 else 11 tmp[i++] = S.charAt(j); 12 } 13 return new String(tmp, 0, i); 14 } 15 }
lc56 Merge Interval
贪心,将interval按照start排好序,按顺序合并overlap的interval 由于题目给的是int[][],int[][0]是start,int[][1]是end。先对start排序,然后对end也排序,为什么?end排完序不就没法和其原本的start匹配了吗?仔细想一想,overlap的interval打乱顺序对最终的merge有影响吗?其实没有,画个图就明白了
1 class Solution { 2 public int[][] merge(int[][] intervals) { 3 4 int m = intervals.length; 5 int[] head = new int[m]; 6 int[] tail = new int[m]; 7 8 for(int i=0; i<m; i++){ 9 head[i] = intervals[i][0]; 10 tail[i] = intervals[i][1]; 11 } 12 13 Arrays.sort(head); 14 Arrays.sort(tail); 15 List<int[]> res = new ArrayList<>(); 16 //int[] tmp = new int[2]; 17 for(int i=0, j=0, loop = 0; i<m; i++){ 18 //int[] tmp = new int[2]; 19 if(i == m-1 || head[i+1] > tail[i]){ 20 tmp[0] = head[j]; 21 tmp[1] = tail[i]; 22 //res.add(new int[]{tmp[0], tmp[1]}); 23 res.add(tmp); 24 25 j = i+1; 26 } 27 } 28 int[][] ans = new int[res.size()][2]; 29 return res.toArray(ans); 30 } 31 }