<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ?LeetCode刷題實戰(zhàn)55:跳躍游戲

          共 1966字,需瀏覽 4分鐘

           ·

          2020-10-03 07:29

          算法的重要性,我就不多說了吧,想去大廠,就必須要經(jīng)過基礎(chǔ)知識和業(yè)務(wù)邏輯面試+算法面試。所以,為了提高大家的算法能力,這個公眾號后續(xù)每天帶大家做一道算法題,題目就從LeetCode上面選 !

          今天和大家聊的問題叫做?跳躍游戲,我們先來看題面:

          https://leetcode-cn.com/problems/jump-game/

          Given an array of non-negative integers, you are initially positioned at the first index of the array.


          Each element in the array represents your maximum jump length at that position.


          Determine if you are able to reach the last index.

          題意


          給定一個非負(fù)整數(shù)數(shù)組,你最初位于數(shù)組的第一個位置。
          數(shù)組中的每個元素代表你在該位置可以跳躍的最大長度。
          判斷你是否能夠到達(dá)最后一個位置。

          樣例

          示例?1:

          輸入: [2,3,1,1,4]
          輸出:
          true
          解釋: 我們可以先跳
          1?步,從位置
          0?到達(dá) 位置
          1, 然后再從位置
          1?跳
          3?步到達(dá)最后一個位置。

          示例?2:

          輸入: [3,2,1,0,4]
          輸出:
          false
          解釋: 無論怎樣,你總會到達(dá)索引為
          3?的位置。但該位置的最大跳躍長度是
          0?, 所以你永遠(yuǎn)不可能到達(dá)最后一個位置。



          解題


          回溯法

          回溯法的思想很簡單,尋找到所有能到達(dá)數(shù)組的最后一個位置的可能路徑,計算其最短值即可。由于是窮舉,其時間復(fù)雜度是很高的,達(dá)到了O(nums[0] + nums[1] + nums[2] + ... + nums[n - 1])級別,其中n為nums數(shù)組的長度。而空間復(fù)雜度則是遞歸深度,是O(n)級別的。


          public?class?Solution?{
          ??
          ??int?steps;
          ?
          ??public?int?jump(int[] nums)?{
          ????????int?n = nums.length;
          ????????steps = n -
          1;
          ????????
          ????????jump(nums,
          0,
          0);
          ????????
          ????????return?steps;
          ????}
          ??
          ??private?void?jump(int[] nums, int?index, int?tempSteps)?{
          ????if(index >= nums.length -
          1) {
          ??????if(index == nums.length -
          1) {
          ????????steps = Math.min(steps, tempSteps);
          ??????}
          ??????return;
          ????}
          ????for?(int?i =
          1; i <= nums[index]; i++) {
          ??????jump(nums, index + i, tempSteps +
          1);
          ????}
          ??}
          }


          動態(tài)規(guī)劃法
          狀態(tài)定義:f(x, y)--------表示從索引x,走到索引y的最短步數(shù)
          狀態(tài)轉(zhuǎn)移:
          (1)如果nums[x] + x >= y,說明一步就可以從索引x走到索引y,f(x, y) = 1。
          (2)如果nums[x] + x < y,f(x, y) = 1 + min{f(x + 1,y), f(x + 2, y), ... , f(x + nums[x], y)}。
          時間復(fù)雜度和空間復(fù)雜度都是O(n ^ 2)級別的。

          public?class?Solution?{
          ?
          ??public?int?jump(int[] nums)?{
          ????????int?n = nums.length;
          ????????if(n == 1) {
          ??????????return?0;
          ????????}
          ????????int[][] steps = new?int[n][n];
          ????????for?(int?i = 0; i < n; i++) {
          ??????for?(int?j = 0; j < n; j++) {
          ????????steps[i][j] = n - 1;
          ??????}
          ????}
          ????????for?(int?i = 0; i < n; i++) {
          ??????steps[i][i] = 0;
          ????}
          ????????for?(int?i = 0; i >= 1?- n; i--) {
          ??????for?(int?j = 0; j < n + i; j++) {
          ????????if(nums[j] + j >= j - i) {
          ??????????steps[j][j - i] = 1;
          ????????}else?{
          ??????????for?(int?k = 1; k <= nums[j]; k++) {
          ????????????steps[j][j - i] = Math.min(steps[j][j - i], 1?+ steps[j + k][j - i]);
          ??????????}
          ????????}
          ??????}
          ????}
          ????????return?steps[0][n - 1];
          ????}
          }


          貪心算法
          前面兩種方法:回法和動態(tài)規(guī)劃都會提前超時。那么必然就得用貪心算法了。貪心算法的本質(zhì)是在動態(tài)規(guī)劃的基礎(chǔ)上舍棄一些不可能的情況,類似于回溯算法的剪枝過程。

          對于本題而言,假設(shè)我們現(xiàn)在在索引i的位置。

          如果索引i的值為0,那么我們不可能再繼續(xù)前進(jìn)了,這種情況舍棄。

          如果索引i的值不為0,那么我們下一步可以走到索引i + k(1 <= k <= nums[i])。而在索引i + k我們又可以走到索引i + k + p(1 <= p <= nums[i + k]),我們選取索引i + k的原則是i + k + p取得最大值。

          public?class?Solution?{
          ??
          ??public?int?jump(int[] nums)?{
          ????????int?n = nums.length;
          ????????int?steps = 0;
          ????????int?index = 0;
          ????????while(index < n - 1) {
          ??????????steps++;
          ??????????int[] lengths = new?int[nums[index]];
          ??????????if(index + nums[index] >= n - 1) {
          ????????????break;
          ??????????}
          ??????????for?(int?i = index + 1; i <= index + nums[index]; i++) {
          ????????lengths[i - index - 1] = i + nums[i];
          ??????}
          ??????????int?max = 0;
          ??????????for?(int?i = 0; i < lengths.length; i++) {
          ????????if(lengths[i] > lengths[max]) {
          ??????????max = i;
          ????????}
          ??????}
          ??????????index = max + index + 1;
          ????????}
          ????????return?steps;
          ????}
          }

          好了,今天的文章就到這里,如果覺得有所收獲,請順手點個在看或者轉(zhuǎn)發(fā)吧,你們的支持是我最大的動力。


          上期推文:


          LeetCode1-50題匯總,速度收藏!
          LeetCode刷題實戰(zhàn)51:N 皇后
          LeetCode刷題實戰(zhàn)52:N皇后 II
          LeetCode刷題實戰(zhàn)53:最大子序和
          LeetCode刷題實戰(zhàn)54:螺旋矩陣


          瀏覽 51
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  午夜怡红院 | 国产精品美女www | 一级黄片美女出来 | 久久成人国产 | 成人自拍偷拍在线视频 |