Longest subarray whose elements form a continuous sequence

后端 未结 7 853
没有蜡笔的小新
没有蜡笔的小新 2021-01-31 05:52

Given an unsorted array of positive integers, find the length of the longest subarray whose elements when sorted are continuous. Can you think of an O(n) solution?

Examp

7条回答
  •  失恋的感觉
    2021-01-31 06:10

    UPD2: The following solution is for a problem when it is not required that subarray is contiguous. I misunderstood the problem statement. Not deleting this, as somebody may have an idea based on mine that will work for the actual problem.


    Here's what I've come up with:

    Create an instance of a dictionary (which is implemented as hash table, giving O(1) in normal situations). Keys are integers, values are hash sets of integers (also O(1)) – var D = new Dictionary>.

    Iterate through the array A and for each integer n with index i do:

    1. Check whether keys n-1 and n+1 are contained in D.
      • if neither key exists, do D.Add(n, new HashSet)
      • if only one of the keys exists, e.g. n-1, do D.Add(n, D[n-1])
      • if both keys exist, do D[n-1].UnionWith(D[n+1]); D[n+1] = D[n] = D[n-1];
    2. D[n].Add(n)

    Now go through each key in D and find the hash set with the greatest length (finding length is O(1)). The greatest length will be the answer.

    To my understanding, the worst case complexity will be O(n*log(n)), only because of the UnionWith operation. I don't know how to calculate the average complexity, but it should be close to O(n). Please correct me if I am wrong.

    UPD: To speak code, here's a test implementation in C# that gives the correct result in both of the OP's examples:

    var A = new int[] {4, 5, 1, 5, 7, 6, 8, 4, 1};
    var D = new Dictionary>();
    
    foreach(int n in A)
    {
        if(D.ContainsKey(n-1) && D.ContainsKey(n+1))
        {
            D[n-1].UnionWith(D[n+1]);
            D[n+1] = D[n] = D[n-1];
        }
        else if(D.ContainsKey(n-1))
        {
            D[n] = D[n-1];
        }
        else if(D.ContainsKey(n+1))
        {
            D[n] = D[n+1];
        }
        else if(!D.ContainsKey(n))
        {
            D.Add(n, new HashSet());
        }
    
        D[n].Add(n);
    }
    
    int result = int.MinValue;
    foreach(HashSet H in D.Values)
    {
        if(H.Count > result)
        {
            result = H.Count;
        }
    }
    
    Console.WriteLine(result);
    

提交回复
热议问题