LeetCode 45跳跃游戏46全排列
原創(chuàng)公眾號:bigsai,回復(fù)進群加入力扣打卡群。
昨日打卡:LeetCode 42字符串相乘&43通配符匹配
跳躍游戲
題目描述:
給定一個非負整數(shù)數(shù)組,你最初位于數(shù)組的第一個位置。
數(shù)組中的每個元素代表你在該位置可以跳躍的最大長度。
你的目標是使用最少的跳躍次數(shù)到達數(shù)組的最后一個位置。
示例:
輸入: [2,3,1,1,4]
輸出: 2
解釋: 跳到最后一個位置的最小跳躍數(shù)是 2。
從下標為 0 跳到下標為 1 的位置,跳 1 步,然后跳 3 步到達數(shù)組的最后一個位置。
說明:
假設(shè)你總是可以到達數(shù)組的最后一個位置。
分析:
這題的話也是運用了不同的方法,從復(fù)雜到簡單。
法一:枚舉
枚舉的思路很簡單,二重循環(huán),第一次循環(huán)遍歷每個數(shù),第二次循環(huán)遍歷長度更新這個范圍內(nèi)能夠更新到的最小跳數(shù)。如果能跳到該位置并且跳躍次數(shù)更少就更新。算法想法簡單,初始需要將除第0位其他設(shè)置為非常大的值(以便有更小的值進行更新)
實現(xiàn)代碼為:
public int jump(int[] nums) {int dp[]=new int[nums.length];for(int i=1;i<nums.length;i++){dp[i]=Integer.MAX_VALUE;}for(int i=0;i<nums.length;i++){int time=dp[i]+1;for(int j=0;j<nums[i];j++){if(j+i+1<nums.length){if(dp[j+i+1]>time)dp[j+i+1]=time;}}}//System.out.println(Arrays.toString(dp));return dp[nums.length-1]; }不過效果很糟糕。
法二:bfs
在這條路行不通之后,就開始尋找另一條路。我便想著用優(yōu)先隊列搜素,具體比較麻煩詳細可以看代碼,主要講第三種方法:
法三:貪心
當我以為9ms很快的時候,發(fā)現(xiàn)原來這個速度還是很慢,就想肯定有一種近O(n)的方法,在這里索性分享給大家。
我們在這里需要的實什么?
- 找到最少的跳躍次數(shù)到達最后
影響我們正常計算的最大障礙是什么?
- 重復(fù)計算、覆蓋情況.無論是跳躍方式和跳躍次數(shù)到達終點都可能不止一種。
但是有一點非常重要的是:每個節(jié)點跳躍的時候是一個從他開始的覆蓋區(qū)間范圍,所以我們能否知道第一次跳多遠。第二次跳多遠呢?第三次呢?
很簡單,所有的起始點是0號位置,也就是第一次一定是從0號跳到的一個區(qū)間節(jié)點。而第二次就是這個區(qū)間內(nèi)能夠跳到的最遠距離都是2次,第三次就是除掉第二次節(jié)點后面能夠跳到的區(qū)間……這樣一直到能夠覆蓋到最后即可完成。
在具體實現(xiàn)的時候,記錄當前的最大長度,用一個time[]數(shù)組表示到達當前節(jié)點需要的跳數(shù),從前往后,如果最大長度大于當前的maxsize,就說明需要加一次更新,如果小于等于maxsize,對應(yīng)位置則不需要更新。
實現(xiàn)代碼為:
public int jump(int[] nums) {int len=nums.length;int time[]=new int[len];int maxsize=0;for(int i=0;i<len;i++){if(i+nums[i]>maxsize){for(int j=maxsize+1;j<=i+nums[i];j++){if(j<len){time[j]=time[i]+1;maxsize=j; }else {break;}}}}return time[len-1]; }
還能優(yōu)化成1ms的就留給你們來了!
全排列
全排列的兩種實現(xiàn)方式這里就不累述,大家可以參考:全排列兩種實現(xiàn)方式
實現(xiàn)方式為:
public List<List<Integer>> permute(int[] nums) {List<List<Integer>>list=new ArrayList<List<Integer>>();arrange(nums,0,nums.length-1,list);return list;}private void arrange(int[] nums, int start, int end, List<List<Integer>> list) {if(start==end){List<Integer>list2=new ArrayList<Integer>();for(int a:nums){list2.add(a);}list.add(list2);}for(int i=start;i<=end;i++){swap(nums,i,start);arrange(nums, start+1, end, list);swap(nums, i, start);}}private void swap(int[] nums, int i, int j) {int team=nums[i];nums[i]=nums[j];nums[j]=team;}本次就到這里啦,感覺不錯記得點贊或一鍵三連哦,個人公眾號:bigsai 回復(fù) bigsai 更多精彩和資源與你分享。
總結(jié)
以上是生活随笔為你收集整理的LeetCode 45跳跃游戏46全排列的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1024我摊牌了,谈谈自己2020剩余两
- 下一篇: 按照这步骤来刷题,两个月你亦能成为王者