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 }

 

posted @ 2019-05-22 11:09  南山南北秋悲  阅读(324)  评论(0编辑  收藏  举报