Maximum number of unique integers

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












I'm given N integers. I need to find the maximum number of unique integers among all the possible contiguous subarrays of size M.



Scanner in = new Scanner(System.in);
Deque deque = new ArrayDeque<Integer>();
int n = in.nextInt();
int m = in.nextInt();
in.nextLine();
String s = in.nextLine();
in.close();

int maxUnique = 0;
List<Integer> numbers = Stream.of(s.split(" "))
.map(Integer::parseInt)
.collect(Collectors.toList());
for (int i = 0; i <= n-m; i++)
HashSet<Integer> unique = new HashSet<>(numbers.subList(i, i+m));
if (maxUnique < unique.size())
maxUnique = unique.size();
if (maxUnique == m)
System.out.println(maxUnique);
return;


System.out.println(maxUnique);


It works fine, but fails on big arrays due to timeout. For example N=100000, M=98777 times out.



How can I improve it?







share|improve this question

















  • 1




    Use a data structure to store values of the numbers you find. Like if the first number is 876, store it. If you find it again, raise it's counter. You can use direct access container like a dynamic array(we call them vectors in C++), but it's minimum size will be n - meaning it will take space, then you can find out maximum and minimum in O(logn) time using another algorithm. It would be easier to use a hash table. I would use vector of pairs in C++.
    – Aniket Chowdhury
    May 26 at 1:54

















up vote
0
down vote

favorite












I'm given N integers. I need to find the maximum number of unique integers among all the possible contiguous subarrays of size M.



Scanner in = new Scanner(System.in);
Deque deque = new ArrayDeque<Integer>();
int n = in.nextInt();
int m = in.nextInt();
in.nextLine();
String s = in.nextLine();
in.close();

int maxUnique = 0;
List<Integer> numbers = Stream.of(s.split(" "))
.map(Integer::parseInt)
.collect(Collectors.toList());
for (int i = 0; i <= n-m; i++)
HashSet<Integer> unique = new HashSet<>(numbers.subList(i, i+m));
if (maxUnique < unique.size())
maxUnique = unique.size();
if (maxUnique == m)
System.out.println(maxUnique);
return;


System.out.println(maxUnique);


It works fine, but fails on big arrays due to timeout. For example N=100000, M=98777 times out.



How can I improve it?







share|improve this question

















  • 1




    Use a data structure to store values of the numbers you find. Like if the first number is 876, store it. If you find it again, raise it's counter. You can use direct access container like a dynamic array(we call them vectors in C++), but it's minimum size will be n - meaning it will take space, then you can find out maximum and minimum in O(logn) time using another algorithm. It would be easier to use a hash table. I would use vector of pairs in C++.
    – Aniket Chowdhury
    May 26 at 1:54













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I'm given N integers. I need to find the maximum number of unique integers among all the possible contiguous subarrays of size M.



Scanner in = new Scanner(System.in);
Deque deque = new ArrayDeque<Integer>();
int n = in.nextInt();
int m = in.nextInt();
in.nextLine();
String s = in.nextLine();
in.close();

int maxUnique = 0;
List<Integer> numbers = Stream.of(s.split(" "))
.map(Integer::parseInt)
.collect(Collectors.toList());
for (int i = 0; i <= n-m; i++)
HashSet<Integer> unique = new HashSet<>(numbers.subList(i, i+m));
if (maxUnique < unique.size())
maxUnique = unique.size();
if (maxUnique == m)
System.out.println(maxUnique);
return;


System.out.println(maxUnique);


It works fine, but fails on big arrays due to timeout. For example N=100000, M=98777 times out.



How can I improve it?







share|improve this question













I'm given N integers. I need to find the maximum number of unique integers among all the possible contiguous subarrays of size M.



Scanner in = new Scanner(System.in);
Deque deque = new ArrayDeque<Integer>();
int n = in.nextInt();
int m = in.nextInt();
in.nextLine();
String s = in.nextLine();
in.close();

int maxUnique = 0;
List<Integer> numbers = Stream.of(s.split(" "))
.map(Integer::parseInt)
.collect(Collectors.toList());
for (int i = 0; i <= n-m; i++)
HashSet<Integer> unique = new HashSet<>(numbers.subList(i, i+m));
if (maxUnique < unique.size())
maxUnique = unique.size();
if (maxUnique == m)
System.out.println(maxUnique);
return;


System.out.println(maxUnique);


It works fine, but fails on big arrays due to timeout. For example N=100000, M=98777 times out.



How can I improve it?









share|improve this question












share|improve this question




share|improve this question








edited May 26 at 5:31









200_success

123k14143399




123k14143399









asked May 26 at 0:53









Maria

31




31







  • 1




    Use a data structure to store values of the numbers you find. Like if the first number is 876, store it. If you find it again, raise it's counter. You can use direct access container like a dynamic array(we call them vectors in C++), but it's minimum size will be n - meaning it will take space, then you can find out maximum and minimum in O(logn) time using another algorithm. It would be easier to use a hash table. I would use vector of pairs in C++.
    – Aniket Chowdhury
    May 26 at 1:54













  • 1




    Use a data structure to store values of the numbers you find. Like if the first number is 876, store it. If you find it again, raise it's counter. You can use direct access container like a dynamic array(we call them vectors in C++), but it's minimum size will be n - meaning it will take space, then you can find out maximum and minimum in O(logn) time using another algorithm. It would be easier to use a hash table. I would use vector of pairs in C++.
    – Aniket Chowdhury
    May 26 at 1:54








1




1




Use a data structure to store values of the numbers you find. Like if the first number is 876, store it. If you find it again, raise it's counter. You can use direct access container like a dynamic array(we call them vectors in C++), but it's minimum size will be n - meaning it will take space, then you can find out maximum and minimum in O(logn) time using another algorithm. It would be easier to use a hash table. I would use vector of pairs in C++.
– Aniket Chowdhury
May 26 at 1:54





Use a data structure to store values of the numbers you find. Like if the first number is 876, store it. If you find it again, raise it's counter. You can use direct access container like a dynamic array(we call them vectors in C++), but it's minimum size will be n - meaning it will take space, then you can find out maximum and minimum in O(logn) time using another algorithm. It would be easier to use a hash table. I would use vector of pairs in C++.
– Aniket Chowdhury
May 26 at 1:54











1 Answer
1






active

oldest

votes

















up vote
4
down vote



accepted










You're almost there. You rebuild the entire HashSet for each of the i-m sub arrays resulting in (i-m)*m worrk.



Change the HashSet to a HashMap and then imagine the sub array as a sliding window. When the window moves one step to the right, count down number at the far left of the old window position in the HashMap and if it becomes zero, remove it. And then add the number to the far right of the new window position to the count of that number in the HashMap (or add the number with count one if it didn't exist), and at each window position take the size of the HashMap. This is (i-m)+m work which is much faster.






share|improve this answer























    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195193%2fmaximum-number-of-unique-integers%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    4
    down vote



    accepted










    You're almost there. You rebuild the entire HashSet for each of the i-m sub arrays resulting in (i-m)*m worrk.



    Change the HashSet to a HashMap and then imagine the sub array as a sliding window. When the window moves one step to the right, count down number at the far left of the old window position in the HashMap and if it becomes zero, remove it. And then add the number to the far right of the new window position to the count of that number in the HashMap (or add the number with count one if it didn't exist), and at each window position take the size of the HashMap. This is (i-m)+m work which is much faster.






    share|improve this answer



























      up vote
      4
      down vote



      accepted










      You're almost there. You rebuild the entire HashSet for each of the i-m sub arrays resulting in (i-m)*m worrk.



      Change the HashSet to a HashMap and then imagine the sub array as a sliding window. When the window moves one step to the right, count down number at the far left of the old window position in the HashMap and if it becomes zero, remove it. And then add the number to the far right of the new window position to the count of that number in the HashMap (or add the number with count one if it didn't exist), and at each window position take the size of the HashMap. This is (i-m)+m work which is much faster.






      share|improve this answer

























        up vote
        4
        down vote



        accepted







        up vote
        4
        down vote



        accepted






        You're almost there. You rebuild the entire HashSet for each of the i-m sub arrays resulting in (i-m)*m worrk.



        Change the HashSet to a HashMap and then imagine the sub array as a sliding window. When the window moves one step to the right, count down number at the far left of the old window position in the HashMap and if it becomes zero, remove it. And then add the number to the far right of the new window position to the count of that number in the HashMap (or add the number with count one if it didn't exist), and at each window position take the size of the HashMap. This is (i-m)+m work which is much faster.






        share|improve this answer















        You're almost there. You rebuild the entire HashSet for each of the i-m sub arrays resulting in (i-m)*m worrk.



        Change the HashSet to a HashMap and then imagine the sub array as a sliding window. When the window moves one step to the right, count down number at the far left of the old window position in the HashMap and if it becomes zero, remove it. And then add the number to the far right of the new window position to the count of that number in the HashMap (or add the number with count one if it didn't exist), and at each window position take the size of the HashMap. This is (i-m)+m work which is much faster.







        share|improve this answer















        share|improve this answer



        share|improve this answer








        edited May 27 at 10:31


























        answered May 26 at 1:03









        Emily L.

        11k12372




        11k12372






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195193%2fmaximum-number-of-unique-integers%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Python Lists

            Aion

            JavaScript Array Iteration Methods