iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0

Given an integer array nums of length n where all the integers of nums are in the range [1, n] and each integer appears once or twice, return an array of all the integers that appears twice.

You must write an algorithm that runs in O(n) time and uses only constant auxiliary space, excluding the space needed to store the output.

給定一個長度為 n 的整數陣列 nums,在此陣列nums中所有的整數都在 [1, n] 的範圍內,且每個整數都有可能出現一次或兩次,請回傳一個陣列其包含了所有出現兩次的整數。

你必須寫一個算法其時間複雜度為 O(n) ,且只能只用常數的輔助空間,不包含儲存輸出的所需空間。
(意思就是可以把要結果利用新的陣列回傳,但是在搜尋陣列nums中重覆出現的正整數時,必須使用in-place(原地)進行處理。

https://ithelp.ithome.com.tw/upload/images/20240908/2016866797ZD7B5YpM.png


其實這題跟昨天的題目處理方式一樣,也是使用Cyclic Sort(循環排序法),講到這我現在才發現,昨天的文章標題竟然把題目名稱寫錯了/images/emoticon/emoticon04.gif,昨天的題目應該是 Leetcode 41. First Missing Positive啊!在這邊更正一下!

寫到這題,我發現其實跟Cyclic Sort(循環排序法)相關的題目,難不是難在要應用或實現Cyclic Sort(循環排序法),而是難在要去想到可以使用Cyclic Sort(循環排序法)解題,基本上只要解題時思路方向有正確導向Cyclic Sort(循環排序法),離後面解題就不遠了。

解題思路
上一題要找不存在的最小正整數,而這一題要找重覆出現兩次的整數,題目很佛心,一開始就告訴你陣列nums中所有的整數都 大於1 且 最多出現兩次。所以,只要使用Cyclic Sort(循環排序法)把各整數放到對應的索引位置後,再把跟索引值不同的整數「揪」出來(表示他肯定已經出現過了),回傳就大功告成了!

步驟

  1. 先利用for loop進行Cyclic Sort(循環排序法),把整數放到對應的索引值位置上
    • 判斷只要 整數值 與 對應索引位置上的整數值 不同,則交換位置
  2. 再一次利用for loop找出索引位置上不是對應的整數,如果不是的話則放進要回傳的陣列中
  3. 回傳結果

程式碼

var findDuplicates = function(nums) {
    for (let i = 0; i < nums.length; i++){
        let correctIndex = nums[i] - 1;
        if (nums[i] !== nums[correctIndex] ){
           [nums[i], nums[correctIndex]] = [nums[correctIndex], nums[i]];
            i--; //只交換一次有可能還是沒有交換到正確的位置上,所以要先i - 1,反覆交換到正確的位置上為止
        }
    }
    let res = [];
    for (let i = 0; i < nums.length; i++){
        if (nums[i] !== i + 1){
            res.push(nums[i]);
        }
    }
    return res;
};

上一篇
[Day26] 41. First Missing Positive
下一篇
[Day28] Patterns: In-place reversal of linked list(原地反轉列表)
系列文
刷題筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言