1. 程式人生 > >Leetcode 491. Increasing Subsequences 上升序列 解題報告

Leetcode 491. Increasing Subsequences 上升序列 解題報告

1 解題思想

hi,好久不見,最近有點忙,更新的很慢。
這道題是給了一個已經排好序的陣列,讓你找出所有的子序列,這些子序列要求同樣是不下降的(就是i+1的數肯定大於等於i),相同的序列不能重複出現,但是允許某個數重複(所以是不重複)。

我給的是最簡單的一個方式,直接回溯,遞迴去找,使用一個hashset去幫助篩選重複。這裡我只加了一個小的優化,就是next,比如3776這樣的,當指標在3時,會首先嚐試第一個7,然後直接跳過第二個7到6,這樣可以節省搜尋。

這不是最優解,其實有個解法是:
統計獨立出現的所有數和其頻率
根據這個數再去生成結果,可以節省很多搜尋時間,例如:
337789
Step1:統計 3:2,7:2,8:1,9:1
Step2:遞迴還原,每一步兩個選擇(意思是都要嘗試),若當前的那個數使用的次數還夠,那麼-1後重復Step2,若還有下一個數,那麼跳過當前數直接到下一個數

每一步Step2的時候,檢查下長度,就可以加入到結果中了,而且這個不需要hashSet,不會重複的。

抱歉,我剛寫的時候理解的不是很好,所以給的答案不是後面想到那種方式。
微博同名

2 原題

Given an integer array, your task is to find all the different possible increasing subsequences of the given array, and the length of an increasing subsequence should be at least 2 .

Example:
Input: [4
, 6, 7, 7] Output: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]] Note: The length of the given array will not exceed 15. The range of integer in the given array is [-100,100]. The given array may contain duplicates, and two equal integers should also be considered as a special case of
increasing sequence.

3 AC解

public class Solution {
    /**
     * 這道題有個很好玩的點:那就是在hashset當中放入陣列時,其檢查的是這個數組裡面的數值是否是一樣的,而不是單純按照物件的地址
     * */
    public List<List<Integer>> findSubsequences(int[] nums) {
        Set<List<Integer>> res= new HashSet<List<Integer>>();
        List<Integer> tmp = new ArrayList<Integer>();
        int[] next = new int[nums.length];
        for(int i=0;i<nums.length;i++){
            int my_next = i+1;
            while(my_next<nums.length && nums[i]==nums[my_next])
                my_next++;
            next[i] = my_next;
        }
        helper(res,tmp,nums,next,0);
        return new ArrayList<List<Integer>>(res);
    }

    /**
     * 採用回溯的方式不停地遞迴,尋找解決方法
     * 其實還有更簡單的方式,但這裡就不多說了
     * */
    private void helper(Set<List<Integer>> res,List<Integer> tmp,int[] nums,int[] next,int index){
        if(tmp.size() > 1){
            res.add(new ArrayList<Integer>(tmp));
        }
        int i=index;
        for(;i<nums.length;){
            if(tmp.size()==0 || tmp.get(tmp.size() - 1) <= nums[i]){
                tmp.add(nums[i]);
                helper(res,tmp,nums,next,i+1);
                tmp.remove(tmp.size() - 1);
            }
            //快速跳到下一個上
            i = next[i];
        }
    }
}