序列每天从0开始_【算法打卡】分割数组为连续子序列
難度:中等
題目:
????給你一個按升序排序的整數數組?num(可能包含重復數字),請你將它們分割成一個或多個長度為 3 的子序列,其中每個子序列都由連續整數組成。
????如果可以完成上述分割,則返回?true?;否則,返回?false?。
------------------------------------------------------
思考:
????題目要求,把數組分割成一或多個連續的子串,那就是要把盡可能多的數字弄成子串,看著有點像可以貪心。
????如果用貪心的話,例如實例2,先盡可能多的從1開始把12345排成一個子序列,然后剩下345排成另一個子序列。
????誒好像可以。
????但是到了示例1這種就8行了。先拿出12345,然后就會只剩下3,不成立,但其實他卻是成立的。
????其實,上面解釋這種只是普通的一般的貪心,我們可以改變一下,升級一下,非一般的貪心。
????一個一個地貪心。? ?
思路:
先用兩個hashMap,一個countNum用來記錄數字出現次數,一個tail記錄以每個數字num結尾的子序列數。
然后遍歷數組,從頭開始,
先判斷countNum的對應數字(例如X)數量是否>0,如果是則再去查找有沒有以數字X-1為結尾的子X序列,有則把數字X續上,tail的X-1結尾的序列數量-1,X結尾的+1,countNum中的X數量-1。
繼續判斷下一位。
如果全部都能連上就是成功。否則有一個不能連上就是失敗。
以示例1來說,
????首先看1,先去countNum查找1的數量,如果>0個,則再去查找tail。如果有以1前一位(也就是0)結尾的,就在后面再續上,然后countNum的num的對應數量-1,tail的前一位的數量-1,1結尾的+1;如果tail沒有以前一位結尾話,就去看后兩位,2和3的countNum是不是同時>0,如果是則連成子串,對應的123的countNum-1,tail對應的3數量+1。
? ??然后看2,因為上面123連成了,123都-1,countNum的2數量=0.
? ? 再看3,上面減了1,countNum的3數量為1,同樣查找tail,沒有以前一位(2)結尾的,直接查看后兩位,有,連成子序列345,countNum各個數-1,tail為5的+1。
? ? 最后都可以連上,成功。
代碼:
public boolean isPossible(int[] nums) { // 用一個哈希表統計每個數字出現的次數 Map countNum = new HashMap<>(); for (int num : nums) countNum.put(num, countNum.getOrDefault(num, 0) + 1); // 定義一個哈希表記錄最長的子序列 Map tail = new HashMap<>(); for (int num : nums) { int count = countNum.getOrDefault(num, 0); if (count <= 0) {//當前元素已經用完,直接跳過 continue; } else if (tail.getOrDefault(num - 1, 0) > 0) {//前面還有數字,可以構成以num結尾的子序列 countNum.put(num, count - 1); tail.put(num - 1, tail.get(num - 1) - 1);//覆蓋當前最長的子序列 tail.put(num, tail.getOrDefault(num, 0) + 1);//當前以num結尾的子序列+1 } else if (countNum.getOrDefault(num + 1, 0) > 0 && countNum.getOrDefault(num + 2, 0) > 0) {//前面無數字構成子序列后,判斷能不能跟后面的構成子序列 countNum.put(num, count - 1); countNum.put(num + 1, countNum.get(num + 1) - 1); countNum.put(num + 2, countNum.get(num + 2) - 1); tail.put(num + 2, tail.getOrDefault(num + 2, 0) + 1);//當前以num+2結尾的子序列+1 } else return false;//前后不能構成子序列則不成立 } return true;}時間復雜度:兩個獨立的循環,一個記錄各個數字個數,一個遍歷數字情況。所以是O(n)
空間復雜度:兩個獨立的哈希表存儲數字個數和子序列數,所以是O(n)
----------------------------------完--------------------------------
淦里良欸
總結
以上是生活随笔為你收集整理的序列每天从0开始_【算法打卡】分割数组为连续子序列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php递归实现冒泡排序,PHP冒泡排序、
- 下一篇: nignx处理Html中SSI技术代码注