面试经典150题(42-44)

leetcode 150道题 计划花两个月时候刷完,今天(第十八天)完成了3道(42-44)150:

昨天肝游戏,浪费了一天。。。

42.(228. 汇总区间)题目描述:

给定一个  无重复元素 的 有序 整数数组 nums 。
返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字 x 。
列表中的每个区间范围 [a,b] 应该按如下格式输出:
"a->b" ,如果 a != b
"a" ,如果 a == b
示例 1:
输入:nums = [0,1,2,4,5,7]
输出:["0->2","4->5","7"]

第一版(这个我之前也写过。。但是写出来效率不是很高)

class Solution {
    public List<String> summaryRanges(int[] nums) {
        int len=nums.length;
        List<String> res=new ArrayList();
        if(len==0){
            return res;
        }
        int left=0;
        int right=0;
        int preNum=nums[0];
        for(int i=1;i<len;i++){
            if(nums[i]-1!=preNum){
                if(left!=right){
                    res.add(nums[left]+"->"+nums[right]);
                }else{
                     res.add(nums[left]+"");
                }
                left=i;
                right=i;
            }
            else{
                right++;
            }
            preNum=nums[i];
        }
        if(left!=right){
            res.add(nums[left]+"->"+nums[right]);
        }else{
            res.add(nums[left]+"");
        }
        return res;
    }
}

第二版(看了解题,我感觉这种带延伸的题好像都是两个while去做的,好像可以总结个模板。。)

class Solution {
    public List<String> summaryRanges(int[] nums) {
        int len=nums.length;
        List<String> res=new ArrayList();
        if(len==0){
            return res;
        }
        int index=0;
        boolean flag=false;
        while(index<len){
            flag=false;
            StringBuilder sb=new StringBuilder();
            sb.append(nums[index++]);
            while(index<len&&nums[index]==nums[index-1]+1){
                index++;
                flag=true;
            }
            if(flag){
                sb.append("->");
                sb.append(nums[index-1]);
            }
            res.add(sb.toString());
        }
        return res;
    }
}

43.(56. 合并区间)题目描述:

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
示例 1:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3][2,6] 重叠, 将它们合并为 [1,6].

第一版(这个题我是有想法的 只不过自己写的排序太垃圾了,还得是工具包的排序。。下面代码带了我写的排序但是没用,用的是 Arrays.sort)

class Solution {
    public int[][] merge(int[][] intervals) {
        int len=intervals.length;
        if(len<=1){
            return intervals;
        }
        int i=0;
        int index=0;
        Arrays.sort(intervals,(v1,v2)->v1[0]-v2[0]);
        int left=intervals[0][0];
        int right=intervals[0][1];
        while(i<len){
            left=intervals[i][0];
            right=intervals[i][1];
            i++;
            while(i<len&&right>=intervals[i][0]){
                // 合并
                if(right<intervals[i][1]){
                    right=intervals[i][1];
                }
                i++;
            }
            intervals[index][0]=left;
            intervals[index][1]=right;
            index++;
        }
        int[][] res=new int[index][2];
        for(int j=0;j<index;j++){
            res[j][0]=intervals[j][0];
            res[j][1]=intervals[j][1];
        }
        return res;
    }
    public void sort(int[][] intervals){
        int len=intervals.length;
        for(int i=0;i<len-1;i++){
            for(int j=i+1;j<len;j++){
                if(intervals[i][0]>intervals[j][0]){
                    int left=intervals[j][0];
                    int right=intervals[j][1];
                    intervals[j][0]=intervals[i][0];
                    intervals[j][1]=intervals[i][1];
                    intervals[i][0]=left;
                    intervals[i][1]=right;
                }
            }
        }
    }
}

44.(57. 插入区间) 题目描述:

给你一个 无重叠的 ,按照区间起始端点排序的区间列表。
在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。
示例 1:
输入:intervals = [[1,3],[6,9]], newInterval = [2,5]
输出:[[1,5],[6,9]]

第一版(这个题看了能有一个小时,情况太多了实在没弄出来,一看解题,可以按照上一个题,先插入然后再去合并。这也算是一个兜底的办法了,我感觉这个兜底的记住就行了。。到时候不至于写不出来)

class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
        int len=intervals.length;
        int[][] temp=new int[len+1][2];
        temp[0][0]=newInterval[0];
        temp[0][1]=newInterval[1];
        for(int i=0;i<len;i++){
            temp[i+1][0]=intervals[i][0];
            temp[i+1][1]=intervals[i][1];
        }
        Arrays.sort(temp,(v1,v2)->v1[0]-v2[0]);
        int resLen=0;
        int index=0;
        int left=temp[0][0];
        int right=temp[0][1];
        while(index<len+1){
            left=temp[index][0];
            right=temp[index][1];
            index++;
            while(index<len+1&&right>=temp[index][0]){
                if(right<temp[index][1]){
                    right=temp[index][1];
                }
                index++;
            }
            temp[resLen][0]=left;
            temp[resLen][1]=right;
            resLen++;
        }
        int[][] res=new int[resLen][2];
        for(int i=0;i<resLen;i++){
            res[i][0]=temp[i][0];
            res[i][1]=temp[i][1];
        }
        return res;
    }
}

加油,第十八天了,早日跳槽!!!

你可能感兴趣的:(面试经典,150,题,面试,算法,leetcode)