LeetCode 55跳跃游戏56合并区间57插入区间
原創公眾號:bigsai 希望和優秀的你做朋友,感覺不錯還請一鍵三連。
回復進群即可加入和200+人一起打卡。上周打卡:
LeetCode 47全排列Ⅱ&48旋轉圖像
LeetCode 49字母異位詞分組&50pow(x,n)&51八皇后
昨日打卡:LeetCode打卡 52八皇后Ⅱ&53最大子序和&54螺旋矩陣
跳躍游戲
給定一個非負整數數組,你最初位于數組的第一個位置。
數組中的每個元素代表你在該位置可以跳躍的最大長度。
判斷你是否能夠到達最后一個位置。
示例 1:
輸入: [2,3,1,1,4]
輸出: true
解釋: 我們可以先跳 1 步,從位置 0 到達 位置 1, 然后再從位置 1 跳 3 步到達最后一個位置。
示例 2:
輸入: [3,2,1,0,4]
輸出: false
解釋: 無論怎樣,你總會到達索引為 3 的位置。但該位置的最大跳躍長度是 0 , 所以你永遠不可能到達最后一個位置。
分析
這題我們可以使用一個O(n)的方法,和前面一些題的方法也很相似,遍歷這個數組,遍歷的同時用一個index標記最大值。如果可以更新最大值那么就更新,如果index比最大值還大,那就直接返回false。
可到達的:
不可到達的:
具體ac代碼:
public boolean canJump(int[] nums) {boolean jud[]=new boolean[nums.length];int maxlen=nums[0];int index=0;while (index<nums.length) {if(index>maxlen)return false;if(index+nums[index]>maxlen){maxlen=index+nums[index];}else {index++;}}return true;}合并區間
合并區間
給出一個區間的集合,請合并所有重疊的區間。
示例 1:
輸入: intervals = [[1,3],[2,6],[8,10],[15,18]]
輸出: [[1,6],[8,10],[15,18]]
解釋: 區間 [1,3] 和 [2,6] 重疊, 將它們合并為 [1,6].
示例 2:
輸入: intervals = [[1,4],[4,5]]
輸出: [[1,5]]
解釋: 區間 [1,4] 和 [4,5] 可被視為重疊區間。
注意:輸入類型已于2019年4月15日更改。 請重置默認代碼定義以獲取新方法簽名。
分析
思路都是一個思路,先把數組進行排序(根據左側數據),排完序的數組遍歷從左往右記錄left,right。
- left,right初始為left=intervals[0][0],right=intervals[0][1]。
- 遍歷的時候如果當前元素intervals[index][0]<right 那么將left,right添加到結果集中,重新賦值left,right初始為當前元素值。
- 如果intervals[index][0]>right條件下,如果 intervals[index][1]>right那么更新right為intervals[index][1]繼續,否則繼續向下。
在代碼實現上提供兩個版本,一個使用List的,一個用數組復用空間,使用List:
public int[][] merge(int[][] intervals) {if(intervals.length==0)return new int[0][0];Arrays.sort(intervals,new Comparator<int []>() {//排序@Overridepublic int compare(int[] o1, int[] o2) {// TODO Auto-generated method stubreturn o1[0]-o2[0];}});List<Integer>list=new ArrayList<Integer>();int left=intervals[0][0],right=intervals[0][1];for(int i=1;i<intervals.length;i++){if(intervals[i][0]<=right){if(intervals[i][1]>right)right=intervals[i][1];}else {list.add(left);list.add(right);left=intervals[i][0];right=intervals[i][1];}}list.add(left);list.add(right);int val[][]=new int [list.size()/2][2];for(int i=0;i<list.size();i+=2){val[i/2][0]=list.get(i);val[i/2][1]=list.get(i+1);}return val; }
而復用數組實現思路如下:
時間差不多6ms。
插入區間
給出一個無重疊的 ,按照區間起始端點排序的區間列表。
在列表中插入一個新的區間,你需要確保列表中的區間仍然有序且不重疊(如果有必要的話,可以合并區間)。
示例 1:
輸入:intervals = [[1,3],[6,9]], newInterval = [2,5]
輸出:[[1,5],[6,9]]
示例 2:
輸入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
輸出:[[1,2],[3,10],[12,16]]
解釋:這是因為新的區間 [4,8] 與 [3,5],[6,7],[8,10] 重疊。
注意:輸入類型已在 2019 年 4 月 15 日更改。請重置為默認代碼定義以獲取新的方法簽名。
和上一題的思想差不多,先排序是肯定的。只不過這里有一點變化:給一個新的數組區間插進來然后再進行合并,在處理上你可以每次遍歷的時候和我們數組進行比較,但是那無疑是一個比較差的方法。所以在這里我先用二分定位到添加的那個區間在原數組中的位置,然后分兩次遍歷進行操作就可以啦。
具體代碼為:
public int[][] insert(int[][] intervals, int[] newInterval) {if(intervals.length==0){int val[][]= {{newInterval[0],newInterval[1]}};return val;}List<Integer>list=new ArrayList<Integer>();//二分找到位置int l=0,r=intervals.length-1;int index=0;while (l<r) {int mid=(l+r)/2;if(intervals[mid][0]==newInterval[0]){l=mid+1;r=mid-1;}else if(intervals[mid][0]<newInterval[0]){l=mid+1;}else {r=mid-1;}}index=l;int left=intervals[0][0],right=intervals[0][1];if(index==0) {left=newInterval[0];right=newInterval[1];}for(int i=0;i<index;i++){if(intervals[i][0]<=right){if(intervals[i][1]>right)right=intervals[i][1];}else {list.add(left);list.add(right);left=intervals[i][0];right=intervals[i][1];}}if(newInterval[0]<=right){if(newInterval[1]>right)right=newInterval[1];}else {list.add(left);list.add(right);left=newInterval[0];right=newInterval[1];}for(int i=index;i<intervals.length;i++){if(intervals[i][0]<=right){if(intervals[i][1]>right)right=intervals[i][1];}else {list.add(left);list.add(right);left=intervals[i][0];right=intervals[i][1];}}list.add(left);list.add(right);int val[][]=new int [list.size()/2][2];for(int i=0;i<list.size();i+=2){val[i/2][0]=list.get(i);val[i/2][1]=list.get(i+1);}return val;}下周繼續!持續更新ing。歡迎關注公眾號:bigsai,一起打卡力扣。還給大家準備一些干貨,一起進步!
總結
以上是生活随笔為你收集整理的LeetCode 55跳跃游戏56合并区间57插入区间的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode打卡 52八皇后Ⅱ53
- 下一篇: 跟我打卡LeetCode 58最后一个单