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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

[Leedcode][JAVA]第[945]题

發(fā)布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Leedcode][JAVA]第[945]题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

【問題描述】

給定整數(shù)數(shù)組 A,每次 move 操作將會選擇任意 A[i],并將其遞增 1。返回使 A 中的每個值都是唯一的最少操作次數(shù)。示例 1:輸入:[1,2,2] 輸出:1 解釋:經(jīng)過一次 move 操作,數(shù)組將變?yōu)?[1, 2, 3]。 示例 2:輸入:[3,2,1,2,1,7] 輸出:6 解釋:經(jīng)過 6 次 move 操作,數(shù)組將變?yōu)?[3, 4, 1, 2, 5, 7]。 可以看出 5 次或 5 次以下的 move 操作是不能讓數(shù)組的每個值唯一的。 提示:0 <= A.length <= 40000 0 <= A[i] < 40000

【解答思路】

1. 排序 O(NlogN)

先排序,再依次遍歷數(shù)組元素,若當前元素小于等于它前一個元素,則將其變?yōu)榍耙粋€數(shù)+1。

class Solution {public int minIncrementForUnique(int[] A) {// 先排序Arrays.sort(A);int move = 0;// 遍歷數(shù)組,若當前元素小于等于它的前一個元素,則將其變?yōu)榍耙粋€數(shù)+1for (int i = 1; i < A.length; i++) {if (A[i] <= A[i - 1]) {int pre = A[i];A[i] = A[i - 1] + 1;move += A[i] - pre;}}return move;}}
2. 注意最后一個的推導 計數(shù)排序 O(N)
class Solution {public int minIncrementForUnique(int[] A) {// counter數(shù)組統(tǒng)計每個數(shù)字的個數(shù)。//(這里為了防止下面遍歷counter的時候每次都走到40000,所以設置了一個max,這個數(shù)據(jù)量不設也行,再額外設置min也行)int[] counter = new int[40001];int max = -1;for (int num: A) {counter[num]++;max = Math.max(max, num);}// 遍歷counter數(shù)組,若當前數(shù)字的個數(shù)cnt大于1個,則只留下1個,其他的cnt-1個后移int move = 0;for (int num = 0; num <= max; num++) {if (counter[num] > 1) {int d = counter[num] - 1;move += d;counter[num + 1] += d;}}// 最后, counter[max+1]里可能會有從counter[max]后移過來的,counter[max+1]里只留下1個,其它的d個后移。// 設 max+1 = x,那么后面的d個數(shù)就是[x+1,x+2,x+3,...,x+d],// 因此操作次數(shù)是[1,2,3,...,d],用求和公式求和。int d = counter[max + 1] - 1;move += (1 + d) * d / 2;return move;} }
3. 線性探測法(含路徑壓縮) O(N) 神仙解法
  • 把原數(shù)組映射到一個地址不沖突的區(qū)域 ,和解決hash沖突的線性探測法比較相似
  • 直接線性探測可能會由于沖突導致反復探測耗時太長 -> 考慮探測的過程中進行路徑壓縮
  • 經(jīng)過某條路徑最終探測到一個空位置x后,將這條路徑上的值都變成空位置所在的下標x,那么假如下次探測的點又是這條路徑上的點,則可以直接跳轉(zhuǎn)到這次探測到的空位置x,從x開始繼續(xù)探測。

下面用樣例2:[3, 2, 1, 2, 1, 7],來模擬一遍線性探測的過程。

模擬的過程中用int move來記錄操作數(shù)(即要求的增量數(shù))。

step1: 插入3:

因為3的位置是空的,所以直接放入3即可。(此時數(shù)組變成了上圖,紅色表示本次的更改)

move = 0 保持不變;

step2: 插入2:

因為2的位置是空的,所以直接放入2即可。(此時數(shù)組變成了上圖,紅色表示本次的更改)

move = 0 保持不變;

step3: 插入1:

因為1的位置是空的,所以直接放入1即可。(此時數(shù)組變成了上圖,紅色表示本次的更改)

move = 0 保持不變;

step4: 插入2:

此時我們發(fā)現(xiàn)2的位置已經(jīng)有值了,于是繼續(xù)向后探測,直到找到空位4,于是2映射到了4。

??并且!!我們要對剛剛走過的路徑2->3->4進行壓縮,即將他們的值都設置為本次探測到的空位4(那么下次探測就可以直接從4往后找了~~)。

(此時數(shù)組變成了上圖,紅色表示本次的更改)

move = move + 4 - 2 = 2;

step5: 插入1:

此時我們發(fā)現(xiàn)1的位置已經(jīng)有值了,于是向后探測,探測到了2,發(fā)現(xiàn)2的位置也有值了,但是由于2在上次的過程中存了上次的空位4,所以我們直接跳轉(zhuǎn)到4+1即從5開始探測就行了(而不需要重復走一遍2->3->4這條路徑嘍!),此時我們發(fā)現(xiàn)5是個空位,因此將1映射到5,并且對剛剛走過的路徑1->2->5進行路徑壓縮 即 使其都映射到5!

(此時數(shù)組變成了上圖,紅色表示本次的更改)

move = move + 5 - 1 = 6;

step6: 插入7:

因為7的位置是空的,所以直接放入7即可。(此時數(shù)組變成了上圖,紅色表示本次的更改)

move = 6 保持不變;

以上,最終move為6。

class Solution {int[] pos = new int [80000];public int minIncrementForUnique(int[] A) {Arrays.fill(pos, -1); // -1表示空位int move = 0;// 遍歷每個數(shù)字a對其尋地址得到位置b, b比a的增量就是操作數(shù)。for (int a: A) {int b = findPos(a); move += b - a;}return move;}// 線性探測尋址(含路徑壓縮)private int findPos(int a) {int b = pos[a];// 如果a對應的位置pos[a]是空位,直接放入即可。if (b == -1) { pos[a] = a;return a;}// 否則向后尋址// 因為pos[a]中標記了上次尋址得到的空位,因此從pos[a]+1開始尋址就行了(不需要從a+1開始)。b = findPos(b + 1); //遞歸pos[a] = b; // ??尋址后的新空位要重新賦值給pos[a]哦,路徑壓縮就是體現(xiàn)在這里。return b;} }
4. 貪心算法 時間復雜度:O(Nlog N) 空間復雜度:O(1)
public int minIncrementForUnique(int[] A) {int len = A.length;if (len == 0) {return 0;}Arrays.sort(A);// 打開調(diào)試// System.out.println(Arrays.toString(A));int preNum = A[0];int res = 0;for (int i = 1; i < len; i++) {// preNum + 1 表示當前數(shù)「最好」是這個值if (A[i] == preNum + 1) {preNum = A[i];} else if (A[i] > preNum + 1) {// 當前這個數(shù)已經(jīng)足夠大,這種情況可以合并到上一個分支preNum = A[i];} else {// A[i] < preNum + 1res += (preNum + 1 - A[i]);preNum++;}}return res;}

【總結(jié)】

  • 思維過于局限 ,統(tǒng)計相同的數(shù)字分別+1,使用兩層循環(huán)導致超時。
  • 思維不跳躍,沒有整體把握,第二種方法和第三種方法看了半天。
  • 轉(zhuǎn)載來自: https://leetcode-cn.com/problems/minimum-increment-to-make-array-unique/solution/ji-shu-onxian-xing-tan-ce-fa-onpai-xu-onlogn-yi-ya/

    總結(jié)

    以上是生活随笔為你收集整理的[Leedcode][JAVA]第[945]题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。