隨機練1
阿新 • • 發佈:2021-07-17
1004. 最大連續1的個數 III
題意: 一個01陣列,求最長連續1其中可以包含k個0
分析: 雙指標,建立左右指標,右指標每次向右移動,遇到0則統計zero出現的次數。如果zero > k,則移動左指標,遇到0則zero--。
class Solution { public int longestOnes(int[] nums, int k) { int left=0,right=0,zeros=0,len=nums.length,res=0; while(right<len){ if(nums[right]==0) zeros++; while(zeros>k){ if(nums[left++]==0) zeros--; } res=Math.max(res,right-left+1); right++; } return res; } }
1306. 跳躍遊戲 III
題意:給定一個非負整數陣列,從下標start出發:下標為i的當前位置可以跳到i+nums[i] or i-nums[i]的位置。問是否可以到達元素值是0的位置。
分析:使用廣度優先bfs:
start
加入佇列。在每一次的搜尋過程中,我們取出隊首的節點u
,它可以到達的位置為u + arr[u]
和u - arr[u]
。
class Solution { public boolean canReach(int[] arr, int start) { Queue<Integer> queue= new LinkedList<>();int len = arr.length; boolean []visited = new boolean[len]; queue.add(start); while(!queue.isEmpty()){ int x = queue.poll(); if(x+arr[x]<len&&!visited[x+arr[x]]){ if(arr[x+arr[x]]==0) return true; visited[x+arr[x]] = true; queue.add(x+arr[x]); } if(x-arr[x]>=0&&!visited[x-arr[x]]){ if(arr[x-arr[x]]==0) return true; visited[x-arr[x]]=true; queue.add(x-arr[x]); } } return false; } }
72. 編輯距離
題意:有A、B兩個字串,經過增、刪、改操作 A-->B
分析:最直觀的是暴力檢查所有編輯方法取最短時間複雜度達到指數級,但我們只需要找到距離最短的序列而不是所有可能的序列。基於以上原則,對A,B的三種操作一共9種操作(A增加,B增加;A減少,B增加...),過濾出明顯不能達到距離最短的操作(A增加,B增加;A減少,B減少;A修改,B修改)。接著我們發現,對單詞
A
刪除一個字元和對單詞B
插入一個字元是等價的(doge->dog)。對單詞A
替換一個字元和對單詞B
替換一個字元是等價的(bat->cat)。這樣一來,本質上能達到目的的操作就三種:1. A 增加
2. A減少(轉化為B增加)
3. A修改
我們用 dp
[i][j]
表示A
的前i
個字母和B
的前j
個字母之間的編輯距離。轉移方程:dp[i][j]=1+min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])
class Solution { public int minDistance(String word1, String word2) { int len1 = word1.length(); int len2 = word2.length(); if(len1*len2==0) return len1+len2; int [][]dp = new int[len1+1][len2+1]; for(int i=0;i<=len1;i++) dp[i][0]=i; for(int j=0;j<=len2;j++) dp[0][j]=j; for(int i=0;i<len1;i++){ for(int j=0;j<len2;j++){ if(word1.charAt(i)==word2.charAt(j)) dp[i+1][j+1]=dp[i][j]; else dp[i+1][j+1]=Math.min(dp[i][j],Math.min(dp[i+1][j],dp[i][j+1]))+1; } } return dp[len1][len2]; } }