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;
}
}
加油,第十八天了,早日跳槽!!!