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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【LeetCode】LeetCode之删除并获得点数——动态规划、排序+动态规划

發布時間:2024/10/5 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【LeetCode】LeetCode之删除并获得点数——动态规划、排序+动态规划 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

🔗【LeetCode】LeetCode之打家劫舍【暴力遞歸、動態規劃、動態規劃之優化空間的具體分析與實現】
🔗【LeetCode】LeetCode之打家劫舍Ⅱ——暴力遞歸+動態規劃解決循環問題+DP空間優化

1.題目描述

給你一個整數數組 nums ,你可以對它進行一些操作。

每次操作中,選擇任意一個 nums[i] ,刪除它并獲得 nums[i] 的點數。之后,你必須刪除 所有 等于 nums[i] - 1 和 nums[i] + 1 的元素。

開始你擁有 0 個點數。返回你能通過這些操作獲得的最大點數。

示例 1:

輸入:nums = [3,4,2]
輸出:6
解釋:
刪除 4 獲得 4 個點數,因此 3 也被刪除。
之后,刪除 2 獲得 2 個點數。總共獲得 6 個點數。

示例 2:

輸入:nums = [2,2,3,3,3,4]
輸出:9
解釋:
刪除 3 獲得 3 個點數,接著要刪除兩個 2 和 4 。
之后,再次刪除 3 獲得 3 個點數,再次刪除 3 獲得 3 個點數。
總共獲得 9 個點數。

提示:

  • 1 <= nums.length <= 2 * 104
  • 1 <= nums[i] <= 104

2.思路分析Ⅰ

根據題目求最大點數,我們首先能夠想到的就是使用動態規劃求解。通過迭代+記憶集能夠解題。
思考該題你會發現,無論怎么想很難直接轉換為動態規劃求解,那么我們只有使用間接的方式【明面上看不出來】,那我們如何向動態規劃的一般思路靠攏呢?

平常最常見的動態規劃一般都是類似于這種dp[n]=max(dp[n-1],dp[n-2]+a);此時我們會發現題目中給定了一個類似的條件:刪除 所有 等于 nums[i] - 1 和 nums[i] + 1 的元素,但是后者是具體的值,而前者是下標。這也是一個問題!

根據上述過程分析,主要使用動態規劃解題的一個問題是題目中的條件是具體的值-1、+1,而動態規劃的一般方式是索引-a、+a。

怎么將值轉換為索引呢?

很簡單,構建一個新數組即可,將舊數組的每一個值充當新數組的索引。當然這個新數組的大小是要根據舊數組的最大值確定的。

那么新數組的索引存儲什么呢?

如果某個數據只有一份,那么它在新數組中的索引和值是一致的。如果數據有n份,那么它的索引就是單個值,它的值是n*單個值。
比如[2,2,2],那么它存儲在索引為2的位置,值為6.

3.動態規劃解題

下面的rob方法就和打家劫舍一樣了:打家劫舍

public int deleteAndEarn(int[] nums) {int maxNum = -1;for (int num : nums) { //求出原數組中的最大值maxNum = Math.max(maxNum, num);}int[] sums = new int[maxNum + 1];//根據最大值構建新數組for (int i = 0; i < nums.length; i++) {sums[nums[i]] += nums[i];}return rob(sums);}//rob打家劫舍解題思路一樣public int rob(int[] sums) {int size = sums.length;int pre = sums[0];int suf = Math.max(pre, sums[1]);int maxEarn = suf;for (int i = 2; i < size; i++) {maxEarn = Math.max(pre + sums[i], suf);pre = suf;suf = maxEarn;}return maxEarn;}

復雜度分析

時間復雜度:O(n * m)m為nums數組中的最大值
空間復雜度:O(m)

4.思路分析Ⅱ

說到底本題不能直接使用動態規劃的原因就是你無法保證前面操作的數據是否會對后續造成影響,比如說[2,3,4,1,6,7,1],你如果要操作2,那么數組中的3和1都要進行刪除,而這3和1是由于無法確定位置,我們很難在迭代過程中對其進行聯系的。另外可以通過排序+劃分子序列來完成

例如數組為[2,4,3,1,9],那么它的執行流程為
1.排序:[1,2,3,4,9]
2.劃分子序列 [最大間隔為1] – >[1,2,3,4]與[9]

4.排序+動態規劃

注意到若 nums 中不存在某個元素 x,則選擇任一小于 x 的元素不會影響到大于 x 的元素的選擇。因此我們可以將nums 排序后,將其劃分成若干連續子數組,子數組內任意相鄰元素之差不超過 11。對每個子數組按照方法一的動態規劃過程計算出結果,累加所有結果即為答案。

public int deleteAndEarn3(int[] nums) {Arrays.sort(nums);List<Integer> list = new ArrayList<>();list.add(nums[0]);int result = 0;int size = 1;for (int i = 1; i < nums.length; i++) {int val = nums[i];if (val == nums[i - 1]) {list.set(size - 1, list.get(size - 1) + val);} else if (nums[i - 1] + 1 == val) {list.add(val);++size;} else {result += rob3(list);list.clear();list.add(nums[i]);size = 1;}}result += rob3(list);return result;}private int rob3(List<Integer> list) {int size = list.size();if (size == 1) {return list.get(0);}int pre = list.get(0);int suf = Math.max(pre, list.get(1));int maxEarn = suf;for (int i = 2; i < size; i++) {maxEarn = Math.max(pre + list.get(i), suf);pre = suf;suf = maxEarn;}return maxEarn;}

復雜度分析:

時間復雜度:O(n*logn),排序花費的時間
空間復雜度:O(n)

總結

以上是生活随笔為你收集整理的【LeetCode】LeetCode之删除并获得点数——动态规划、排序+动态规划的全部內容,希望文章能夠幫你解決所遇到的問題。

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