599. 两个列表的最小索引总和 / 56. 合并区间 / 57. 插入区间

599. 两个列表的最小索引总和【简单题】【每日一题】

思路:【哈希表】

  1. 将list2的集合元素按元素-下标的键值对方式存入哈希表map2中,定义list用来存放可能的数据,定义最小索引和min,初值为int上界。
  2. fori循环遍历list1,如果当前元素在map2中出现,则定义sum存放当前元素下标 i与map2中当前元素对应的值之和。如果sum小于min,那么就将list清空,并将当前元素s存入list中,如果sum=min,那么将当前元素存入list中。
  3. 最后将list转为String[]数组返回即可。

代码:

class Solution {
    public String[] findRestaurant(String[] list1, String[] list2) {
        int min = Integer.MAX_VALUE;
        Map<String,Integer> map2 = new HashMap<>();
        for (int i = 0; i < list2.length; i++) {
            map2.put(list2[i], i);
        }
        List<String> list = new ArrayList<>();
        for (int i = 0; i < list1.length; i++) {
            String s = list1[i];
            if (map2.containsKey(s)){
                int sum = i + map2.get(s);
                if (sum < min){
                    min = sum;
                    list.clear();
                    list.add(s);
                }else if (sum == min){
                    list.add(s);
                }
            }
        }
        return list.toArray(new String[0]);
    }
}

56. 合并区间【中等题】

思路:

  1. 先对区间数组进行排序,如果每个区间的左端点不同,则按左端点升序排列,如果左端点相同,则按右端点升序排列。
  2. 定义list用来存储合并后的区间。
  3. 遍历排序后的区间数组intervals,定义当前区间左端点为 l,右端点为 r,如果list为空 或者 list的最后一个区间的右端点比当前区间左端点 l
    要小,那么说明当前区间与list的最后一个区间不重合,于是将当前区间的左右端点直接添加进list中;否则的话说明当前区间与list的最后一个区间有重合,那么就更新list的最后一个区间的右端点,更新为原右端点和当前区间的右端点
    r 两者中的最大值。
  4. 最后将list转换为二维数组返回。

代码:

class Solution {
    public int[][] merge(int[][] intervals) {
        Arrays.sort(intervals, (e1,e2) ->(e1[0] == e2[0] ? (e1[1]-e2[1]) : (e1[0]-e2[0])));
        List<int[]> list = new ArrayList<>();
        for (int[] interval : intervals) {
            int l = interval[0], r = interval[1];
            if (list.size() == 0 || list.get(list.size() - 1)[1] < l) {//与上一个区间不重合,直接添加
                list.add(new int[]{l, r});
            } else {//与上一个区间有重合,更新更靠右的区间端点
                list.get(list.size() - 1)[1] = Math.max(list.get(list.size() - 1)[1], r);
            }
        }
        return list.toArray(new int[0][]);
    }
}

57. 插入区间【中等题】

思路:

看注释

代码:

class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
        //由题意知,未插入前,区间有序且无重叠,因此要保证插入区间之后仍然有序无重叠
        //只需注意区间范围在插入区间两侧且会产生交集的区间即可
        List<int[]> list = new ArrayList<>();
        int l = newInterval[0],r = newInterval[1];
        boolean flag = false;//区间插入标志
        for (int[] interval : intervals) {
            if (interval[0] > r){
                //当前区间在插入区间的右侧且无交集
                if (!flag){//此时如果区间未插入。就将其插入list末尾,并将区间插入标志位置为true
                    list.add(new int[]{l,r});
                    flag = true;
                }
                //此时插入区间已经插入,后面的区间不用更改,后续区间原样添加即可
                list.add(interval);
                continue;
            }
            if (interval[1] < l){
                //当前区间在插入区间的左侧且无交集
                //此时由于还未与插入区间产生交集,于是当前区间之间原样插入即可
                list.add(interval);
                continue;
            }
            //排除上述两种情况之后,就是在插入区间左侧或右侧且与插入区间有交集的情况
            //此时需要确定交集范围,让左端点尽量小,让右端点尽量大,并一直更新
            //直到原区间不会与可能重合的范围有任何交集
            l = Math.min(l,interval[0]);
            r = Math.max(r,interval[1]);
        }
        if (!flag){//如果遍历结束区间仍未插入,那么就将其插入list末尾
            list.add(new int[]{l,r});
        }
        return list.toArray(new int[0][]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值