日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode 45跳跃游戏46全排列

發布時間:2025/3/20 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode 45跳跃游戏46全排列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原創公眾號:bigsai,回復進群加入力扣打卡群。
昨日打卡:LeetCode 42字符串相乘&43通配符匹配

跳躍游戲

題目描述:

給定一個非負整數數組,你最初位于數組的第一個位置。
數組中的每個元素代表你在該位置可以跳躍的最大長度。
你的目標是使用最少的跳躍次數到達數組的最后一個位置。

示例:

輸入: [2,3,1,1,4]
輸出: 2
解釋: 跳到最后一個位置的最小跳躍數是 2。
從下標為 0 跳到下標為 1 的位置,跳 1 步,然后跳 3 步到達數組的最后一個位置。
說明:
假設你總是可以到達數組的最后一個位置。

分析:

這題的話也是運用了不同的方法,從復雜到簡單。

法一:枚舉

枚舉的思路很簡單,二重循環,第一次循環遍歷每個數,第二次循環遍歷長度更新這個范圍內能夠更新到的最小跳數。如果能跳到該位置并且跳躍次數更少就更新。算法想法簡單,初始需要將除第0位其他設置為非常大的值(以便有更小的值進行更新)

實現代碼為:

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
在這條路行不通之后,就開始尋找另一條路。我便想著用優先隊列搜素,具體比較麻煩詳細可以看代碼,主要講第三種方法:

class node {int time;int index;public node(int time,int index) {this.time=time;this.index=index;} }public int jump(int[] nums) {boolean jud[]=new boolean[nums.length];Queue<node>q1=new PriorityQueue<node>(new Comparator<node>() {@Overridepublic int compare(node o1, node o2) {if(o1.time==o2.time){return o2.index-o1.index;}return o1.time-o2.time;}});q1.add(new node(0, 0));while (!q1.isEmpty()) {node team=q1.poll();int time=team.time+1;int index=team.index;for(int i=1;i<=nums[index];i++)//前進的位置{if(index+i<nums.length&&!jud[index+i]){if(index+i==nums.length-1)return time;q1.add(new node(time, index+i));jud[index+i]=true;}}}return 0;}


法三:貪心
當我以為9ms很快的時候,發現原來這個速度還是很慢,就想肯定有一種近O(n)的方法,在這里索性分享給大家。

我們在這里需要的實什么?

  • 找到最少的跳躍次數到達最后

影響我們正常計算的最大障礙是什么?

  • 重復計算、覆蓋情況.無論是跳躍方式和跳躍次數到達終點都可能不止一種。


但是有一點非常重要的是:每個節點跳躍的時候是一個從他開始的覆蓋區間范圍,所以我們能否知道第一次跳多遠。第二次跳多遠呢?第三次呢?

很簡單,所有的起始點是0號位置,也就是第一次一定是從0號跳到的一個區間節點。而第二次就是這個區間內能夠跳到的最遠距離都是2次,第三次就是除掉第二次節點后面能夠跳到的區間……這樣一直到能夠覆蓋到最后即可完成。

在具體實現的時候,記錄當前的最大長度,用一個time[]數組表示到達當前節點需要的跳數,從前往后,如果最大長度大于當前的maxsize,就說明需要加一次更新,如果小于等于maxsize,對應位置則不需要更新。

實現代碼為:

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]; }


還能優化成1ms的就留給你們來了!

全排列

全排列的兩種實現方式這里就不累述,大家可以參考:全排列兩種實現方式

實現方式為:

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 回復 bigsai 更多精彩和資源與你分享。

總結

以上是生活随笔為你收集整理的LeetCode 45跳跃游戏46全排列的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。