Subset of the maximum number of consecutive values

Source: Internet
Author: User

For an integer array a [], find the subset that contains the maximum number of consecutive numbers, for example, 15, 7, 12, 6, 14, 13, 9, 11, then return: 5: [11, 12, 13, 14, 15].

The simplest method is sort and scan it again, but it requires o (nlgn). Is there any O (n) method?

Ideas:

Some people use map on the Internet. I think the complexity of map is O (nlgn ). The query set can achieve O (n), but the complete code has not been seen on the Internet, so I wrote one myself.

First, let's briefly introduce and check the content of the set. The introduction to algorithms and relevant information can be found on the Internet.

The query set is a simple and widely used algorithm and data structure. The query set is a set of several non-intersecting sets, which allows you to quickly merge and determine the set where elements are located. There are many applications, such as finding the number of connected components in an undirected graph and implementing the kruskal algorithm.

The query set allows you to perform the following three operations:

1. Make (x): initializes each element into a set. After initialization, the parent node of each element is itself.

2. Find (x): searches for the set where an element is located. The set where an element is located is identified by the ancestor node of this set. To determine whether two elements belong to the same set, you only need to check whether the ancestor nodes of the set are the same.

3. Union (x, y): merge the two sets where x and y are located. First, use Find () to Find the ancestor of the two sets. If these two ancestor nodes are not the same node, point one of the ancestor nodes to another. (The specific ancestor points to which ancestor can be determined based on the actual situation)


Optimization of query set: In the Find function, the complexity of searching for ancestor nodes is O (n ). When we recursively Find the ancestor node, we direct all the child nodes in this path to the ancestor, so that the complexity of the next Find will become O (1 ).

Back to the question, call Make (x) to convert each element into a query set, scan a [I] at a time, and check whether a [I]-1 exists, if Union (a [I], a [I]-1) is called, check whether a [I] + 1 exists. If Union (a [I] + 1, a [I]). Update the size of the set while merging. The next question is how to determine whether a [I]-1 and a [I] + 1 exist, which can be solved by hash and the complexity is O (1 ).

The operations for checking the set in this question are based on the underlying standards. We use p [I] to represent the subscript of the parent node of a [I], and len [I] to represent the size of the set with a [I] as the root, when merging, we always point the ancestor of a smaller value set to the ancestor of a smaller value set. In this way, we only need to record the length of the ancestor node of the smaller value set. Finally, scan the arrays a [] and len [] to find the [I] corresponding to maxLen with the maximum length. The final result is: a [I]-maxLen + 1, a [I]-maxLen + 2,..., a [I].

 

# Include <iostream> # include <vector> # include <assert. h> using namespace std; void Make (vector <int> & p, vector <int> & len, int x) {p [x] = x; // x is the subscript len [x] = 1; // The set length of a node is 1} int Find (vector <int> & p, int x) {if (x! = P [x]) p [x] = Find (p, p [x]); // The path is compressed to compress all child nodes in the path, returns p [x];} void Union (vector <int> & p, vector <int> & len, int x, int y) {// when passing a parameter, you must pass the vertex with a smaller value to x, and the vertex with a smaller value to yint px = Find (p, x ); int py = Find (p, y); if (px = py) return; p [py] = px; // point py to pxlen [px] + = len [py]; // px is the new ancestor. The px value must be greater than the py value, so only update the px length.} void Longest (vector <int> & ivec, int & max, int & maxLen) {assert (! Ivec. empty (); int size = ivec. size (); vector <int> p (size); vector <int> len (size); for (int I = 0; I <size; ++ I) make (p, len, I); int MAX = ivec [0]; for (int I = 1; I <size; ++ I) {if (ivec [I]> MAX) MAX = ivec [I];} vector <int> hash (MAX + 2),-1 ); // query whether a [I]-1 and a [I] + 1 exist for (int I = 0; I <size; ++ I) hash [ivec [I] = I; for (int I = 0; I <size; ++ I) {int num = ivec [I]; if (hash [num] = I) // This condition is used to process duplicate numbers. if hash [nu M]! = I, indicating that there is num repeat after I, only the last one can be processed {if (hash [num-1]! =-1) Union (p, len, I, hash [num-1]); if (hash [num + 1]! =-1) Union (p, len, hash [num + 1], I) ;}max = ivec [0]; maxLen = len [0]; for (int I = 1; I <size; ++ I) {if (len [I]> maxLen) {maxLen = len [I]; max = ivec [I] ;}}int main () {int a [] = {15, 7, 12, 6, 14, 13, 9, 11 }; vector <int> ivec (a, a + 8); int max, maxLen; Longest (ivec, max, maxLen); for (int I = max-maxLen + 1; I <= max; ++ I) cout <I <''; cout <endl; return 0 ;}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.