Is there any way to compare each element in an array using a single loop?











up vote
2
down vote

favorite












I need to print the least difference between any two elements of an int array.



each element of array A is less than equal to its length.



1 <= A[i] <= A.length;


I have tried this below given approach in Java -
But this takes more than 1 second to find results when array size is given ~10^5.



I think it may be a naive approach. Is there any way i can optimize it further?
Can it be done in O(n) time complexity?



static int findResult(int arr)
{
int max = Integer.MAX_VALUE;
HashSet<Integer> hs = new HashSet<Integer>();
for(int obj : arr)
{
hs.add(obj);
}
if(hs.size()==1 )
{
return 0; // if all elements are same
}
for(int i=0; i<arr.length; i++)
{
for(int j=i+1; j<arr.length; j++)
{
int value = Math.abs(a[i]-a[j]);
if(value<max)
{
max = value;
}

}
}
return max; // returns the smallest positive difference
}









share|improve this question






















  • You can sort the array, and then look for the smallest difference, this is then always between the current and next item.
    – Willem Van Onsem
    Nov 11 at 15:18










  • It will work in a few cases. like 1 2 5 7 1. Sorted - 1 1 2 5 7. but will fail(worst case) - 5 2 3 1 5. sorted -1 2 3 5 5. anyway thanks :)
    – ysoserious9211
    Nov 11 at 15:25












  • No, for all, since then you iterate over the "consecutive" elements, and each time calculate the difference.
    – Willem Van Onsem
    Nov 11 at 15:26















up vote
2
down vote

favorite












I need to print the least difference between any two elements of an int array.



each element of array A is less than equal to its length.



1 <= A[i] <= A.length;


I have tried this below given approach in Java -
But this takes more than 1 second to find results when array size is given ~10^5.



I think it may be a naive approach. Is there any way i can optimize it further?
Can it be done in O(n) time complexity?



static int findResult(int arr)
{
int max = Integer.MAX_VALUE;
HashSet<Integer> hs = new HashSet<Integer>();
for(int obj : arr)
{
hs.add(obj);
}
if(hs.size()==1 )
{
return 0; // if all elements are same
}
for(int i=0; i<arr.length; i++)
{
for(int j=i+1; j<arr.length; j++)
{
int value = Math.abs(a[i]-a[j]);
if(value<max)
{
max = value;
}

}
}
return max; // returns the smallest positive difference
}









share|improve this question






















  • You can sort the array, and then look for the smallest difference, this is then always between the current and next item.
    – Willem Van Onsem
    Nov 11 at 15:18










  • It will work in a few cases. like 1 2 5 7 1. Sorted - 1 1 2 5 7. but will fail(worst case) - 5 2 3 1 5. sorted -1 2 3 5 5. anyway thanks :)
    – ysoserious9211
    Nov 11 at 15:25












  • No, for all, since then you iterate over the "consecutive" elements, and each time calculate the difference.
    – Willem Van Onsem
    Nov 11 at 15:26













up vote
2
down vote

favorite









up vote
2
down vote

favorite











I need to print the least difference between any two elements of an int array.



each element of array A is less than equal to its length.



1 <= A[i] <= A.length;


I have tried this below given approach in Java -
But this takes more than 1 second to find results when array size is given ~10^5.



I think it may be a naive approach. Is there any way i can optimize it further?
Can it be done in O(n) time complexity?



static int findResult(int arr)
{
int max = Integer.MAX_VALUE;
HashSet<Integer> hs = new HashSet<Integer>();
for(int obj : arr)
{
hs.add(obj);
}
if(hs.size()==1 )
{
return 0; // if all elements are same
}
for(int i=0; i<arr.length; i++)
{
for(int j=i+1; j<arr.length; j++)
{
int value = Math.abs(a[i]-a[j]);
if(value<max)
{
max = value;
}

}
}
return max; // returns the smallest positive difference
}









share|improve this question













I need to print the least difference between any two elements of an int array.



each element of array A is less than equal to its length.



1 <= A[i] <= A.length;


I have tried this below given approach in Java -
But this takes more than 1 second to find results when array size is given ~10^5.



I think it may be a naive approach. Is there any way i can optimize it further?
Can it be done in O(n) time complexity?



static int findResult(int arr)
{
int max = Integer.MAX_VALUE;
HashSet<Integer> hs = new HashSet<Integer>();
for(int obj : arr)
{
hs.add(obj);
}
if(hs.size()==1 )
{
return 0; // if all elements are same
}
for(int i=0; i<arr.length; i++)
{
for(int j=i+1; j<arr.length; j++)
{
int value = Math.abs(a[i]-a[j]);
if(value<max)
{
max = value;
}

}
}
return max; // returns the smallest positive difference
}






algorithm optimization array-algorithms






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 11 at 15:13









ysoserious9211

137




137












  • You can sort the array, and then look for the smallest difference, this is then always between the current and next item.
    – Willem Van Onsem
    Nov 11 at 15:18










  • It will work in a few cases. like 1 2 5 7 1. Sorted - 1 1 2 5 7. but will fail(worst case) - 5 2 3 1 5. sorted -1 2 3 5 5. anyway thanks :)
    – ysoserious9211
    Nov 11 at 15:25












  • No, for all, since then you iterate over the "consecutive" elements, and each time calculate the difference.
    – Willem Van Onsem
    Nov 11 at 15:26


















  • You can sort the array, and then look for the smallest difference, this is then always between the current and next item.
    – Willem Van Onsem
    Nov 11 at 15:18










  • It will work in a few cases. like 1 2 5 7 1. Sorted - 1 1 2 5 7. but will fail(worst case) - 5 2 3 1 5. sorted -1 2 3 5 5. anyway thanks :)
    – ysoserious9211
    Nov 11 at 15:25












  • No, for all, since then you iterate over the "consecutive" elements, and each time calculate the difference.
    – Willem Van Onsem
    Nov 11 at 15:26
















You can sort the array, and then look for the smallest difference, this is then always between the current and next item.
– Willem Van Onsem
Nov 11 at 15:18




You can sort the array, and then look for the smallest difference, this is then always between the current and next item.
– Willem Van Onsem
Nov 11 at 15:18












It will work in a few cases. like 1 2 5 7 1. Sorted - 1 1 2 5 7. but will fail(worst case) - 5 2 3 1 5. sorted -1 2 3 5 5. anyway thanks :)
– ysoserious9211
Nov 11 at 15:25






It will work in a few cases. like 1 2 5 7 1. Sorted - 1 1 2 5 7. but will fail(worst case) - 5 2 3 1 5. sorted -1 2 3 5 5. anyway thanks :)
– ysoserious9211
Nov 11 at 15:25














No, for all, since then you iterate over the "consecutive" elements, and each time calculate the difference.
– Willem Van Onsem
Nov 11 at 15:26




No, for all, since then you iterate over the "consecutive" elements, and each time calculate the difference.
– Willem Van Onsem
Nov 11 at 15:26












3 Answers
3






active

oldest

votes

















up vote
4
down vote



accepted










With 1≤xi≤n: O(n)



Since for every xi it holds that 1≤xi≤n, it holds that, due to the pigeonhole principle, either all values exist exactly once, or a value exists two or more times.



In the former case, the difference is 1 (for an array larger than 1 element), in the latter case, the result is 0, since then there are two items that are exactly equal.



We can thus iterate over the array and keep track of the numbers. If a number already exists once, we return 0, otherwise, we return 1, like:



// only if it holds that for all i, 1 <= arr[i] <= arr.length
static int findResult(int arr) {
bool found = new bool[arr.length]
for(int i = 0; i < arr.length; i++) {
if(found[arr[i]-1]) {
return 0;
} else {
found[arr[i]-1] = true;
}
}
return 1;
}


For a random array that satisfies the condition with n elements, in n!/nn of the cases, it will return 1, and in the other cases, it will return 0, so the average over random input is n!/nn. As n grows larger, it becomes very unlikely that there are no "collisions", and thus, as @YvesDaoust says, the approximation of 0 is very likely.



Without 1≤xi≤n: O(n log n)



In case we drop the constraint, we can first sort the array, and in that case, we iterate over consecutive elements:



static int findResult(int arr) {
Arrays.sort(arr);
int dmin = arr[1] - arr[0];
for(int i = 2; i < arr.length; i++) {
int d = arr[i] - arr[i-1];
if(d < dmin) {
if(d == 0) {
return 0;
}
dmin = d;
}
}
return dmin;
}





share|improve this answer



















  • 1




    An approximate solution is possible in O(1): return 0. This will be correct in a vast majority of cases ;-)
    – Yves Daoust
    Nov 11 at 15:34








  • 1




    First one will do. since there have be that constraint(1<=arr[i]<=arr.length). It should work. Thanks man! :-)
    – ysoserious9211
    Nov 11 at 15:43






  • 1




    1 micro-optimization in your 2nd approach. You return dmin the moment you come to know it's 0 .
    – vivek_23
    Nov 11 at 16:50






  • 1




    @WillemVanOnsem maybe I miss something but shouldn't the first findResult code should check in the if statement: if (found[arr[i]]) return 0 else found[arr[i]] = true? (Instead of found[i-1])
    – David Winder
    Nov 11 at 16:54






  • 2




    @DavidWinder: I made a mistake, it should be found[arr[i]-1], thanks :)
    – Willem Van Onsem
    Nov 11 at 17:00


















up vote
1
down vote













I am assuming that the A's are integer, otherwise the condition 1 <= A[i] <= A.len has no relevance.



Then there is an O(n) solution by using an histogram.




  1. declare an array of counters of size A.length;


  2. count the multiplicities of the elements of A;


  3. scan this histogram to find the closest non-empty bins.





Note that this solution assumes that only nonzero differences are considered. If zero difference counts, then Willem's answer is better.






share|improve this answer






























    up vote
    0
    down vote













    (Adding to the above answers)



    If you need to do this with O(1) extra space, you can use the following trick on the input sequence A:



    for a in A[1...n]:        // a is an element in A; A is 1-indexed; 1 <= a <= n
    if M < A[a % M]:
    return 0
    A[a % M] += M
    return 1


    Here M (> n) is such that M + n doesn't overflow. The trick can be easily modified to use instead an M which is less than -n.



    Caveats:




    1. Requires random (i.e. O(1)) access to the elements of A.

    2. Not cache-friendly.






    share|improve this answer























      Your Answer






      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: "1"
      };
      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: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53250101%2fis-there-any-way-to-compare-each-element-in-an-array-using-a-single-loop%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      4
      down vote



      accepted










      With 1≤xi≤n: O(n)



      Since for every xi it holds that 1≤xi≤n, it holds that, due to the pigeonhole principle, either all values exist exactly once, or a value exists two or more times.



      In the former case, the difference is 1 (for an array larger than 1 element), in the latter case, the result is 0, since then there are two items that are exactly equal.



      We can thus iterate over the array and keep track of the numbers. If a number already exists once, we return 0, otherwise, we return 1, like:



      // only if it holds that for all i, 1 <= arr[i] <= arr.length
      static int findResult(int arr) {
      bool found = new bool[arr.length]
      for(int i = 0; i < arr.length; i++) {
      if(found[arr[i]-1]) {
      return 0;
      } else {
      found[arr[i]-1] = true;
      }
      }
      return 1;
      }


      For a random array that satisfies the condition with n elements, in n!/nn of the cases, it will return 1, and in the other cases, it will return 0, so the average over random input is n!/nn. As n grows larger, it becomes very unlikely that there are no "collisions", and thus, as @YvesDaoust says, the approximation of 0 is very likely.



      Without 1≤xi≤n: O(n log n)



      In case we drop the constraint, we can first sort the array, and in that case, we iterate over consecutive elements:



      static int findResult(int arr) {
      Arrays.sort(arr);
      int dmin = arr[1] - arr[0];
      for(int i = 2; i < arr.length; i++) {
      int d = arr[i] - arr[i-1];
      if(d < dmin) {
      if(d == 0) {
      return 0;
      }
      dmin = d;
      }
      }
      return dmin;
      }





      share|improve this answer



















      • 1




        An approximate solution is possible in O(1): return 0. This will be correct in a vast majority of cases ;-)
        – Yves Daoust
        Nov 11 at 15:34








      • 1




        First one will do. since there have be that constraint(1<=arr[i]<=arr.length). It should work. Thanks man! :-)
        – ysoserious9211
        Nov 11 at 15:43






      • 1




        1 micro-optimization in your 2nd approach. You return dmin the moment you come to know it's 0 .
        – vivek_23
        Nov 11 at 16:50






      • 1




        @WillemVanOnsem maybe I miss something but shouldn't the first findResult code should check in the if statement: if (found[arr[i]]) return 0 else found[arr[i]] = true? (Instead of found[i-1])
        – David Winder
        Nov 11 at 16:54






      • 2




        @DavidWinder: I made a mistake, it should be found[arr[i]-1], thanks :)
        – Willem Van Onsem
        Nov 11 at 17:00















      up vote
      4
      down vote



      accepted










      With 1≤xi≤n: O(n)



      Since for every xi it holds that 1≤xi≤n, it holds that, due to the pigeonhole principle, either all values exist exactly once, or a value exists two or more times.



      In the former case, the difference is 1 (for an array larger than 1 element), in the latter case, the result is 0, since then there are two items that are exactly equal.



      We can thus iterate over the array and keep track of the numbers. If a number already exists once, we return 0, otherwise, we return 1, like:



      // only if it holds that for all i, 1 <= arr[i] <= arr.length
      static int findResult(int arr) {
      bool found = new bool[arr.length]
      for(int i = 0; i < arr.length; i++) {
      if(found[arr[i]-1]) {
      return 0;
      } else {
      found[arr[i]-1] = true;
      }
      }
      return 1;
      }


      For a random array that satisfies the condition with n elements, in n!/nn of the cases, it will return 1, and in the other cases, it will return 0, so the average over random input is n!/nn. As n grows larger, it becomes very unlikely that there are no "collisions", and thus, as @YvesDaoust says, the approximation of 0 is very likely.



      Without 1≤xi≤n: O(n log n)



      In case we drop the constraint, we can first sort the array, and in that case, we iterate over consecutive elements:



      static int findResult(int arr) {
      Arrays.sort(arr);
      int dmin = arr[1] - arr[0];
      for(int i = 2; i < arr.length; i++) {
      int d = arr[i] - arr[i-1];
      if(d < dmin) {
      if(d == 0) {
      return 0;
      }
      dmin = d;
      }
      }
      return dmin;
      }





      share|improve this answer



















      • 1




        An approximate solution is possible in O(1): return 0. This will be correct in a vast majority of cases ;-)
        – Yves Daoust
        Nov 11 at 15:34








      • 1




        First one will do. since there have be that constraint(1<=arr[i]<=arr.length). It should work. Thanks man! :-)
        – ysoserious9211
        Nov 11 at 15:43






      • 1




        1 micro-optimization in your 2nd approach. You return dmin the moment you come to know it's 0 .
        – vivek_23
        Nov 11 at 16:50






      • 1




        @WillemVanOnsem maybe I miss something but shouldn't the first findResult code should check in the if statement: if (found[arr[i]]) return 0 else found[arr[i]] = true? (Instead of found[i-1])
        – David Winder
        Nov 11 at 16:54






      • 2




        @DavidWinder: I made a mistake, it should be found[arr[i]-1], thanks :)
        – Willem Van Onsem
        Nov 11 at 17:00













      up vote
      4
      down vote



      accepted







      up vote
      4
      down vote



      accepted






      With 1≤xi≤n: O(n)



      Since for every xi it holds that 1≤xi≤n, it holds that, due to the pigeonhole principle, either all values exist exactly once, or a value exists two or more times.



      In the former case, the difference is 1 (for an array larger than 1 element), in the latter case, the result is 0, since then there are two items that are exactly equal.



      We can thus iterate over the array and keep track of the numbers. If a number already exists once, we return 0, otherwise, we return 1, like:



      // only if it holds that for all i, 1 <= arr[i] <= arr.length
      static int findResult(int arr) {
      bool found = new bool[arr.length]
      for(int i = 0; i < arr.length; i++) {
      if(found[arr[i]-1]) {
      return 0;
      } else {
      found[arr[i]-1] = true;
      }
      }
      return 1;
      }


      For a random array that satisfies the condition with n elements, in n!/nn of the cases, it will return 1, and in the other cases, it will return 0, so the average over random input is n!/nn. As n grows larger, it becomes very unlikely that there are no "collisions", and thus, as @YvesDaoust says, the approximation of 0 is very likely.



      Without 1≤xi≤n: O(n log n)



      In case we drop the constraint, we can first sort the array, and in that case, we iterate over consecutive elements:



      static int findResult(int arr) {
      Arrays.sort(arr);
      int dmin = arr[1] - arr[0];
      for(int i = 2; i < arr.length; i++) {
      int d = arr[i] - arr[i-1];
      if(d < dmin) {
      if(d == 0) {
      return 0;
      }
      dmin = d;
      }
      }
      return dmin;
      }





      share|improve this answer














      With 1≤xi≤n: O(n)



      Since for every xi it holds that 1≤xi≤n, it holds that, due to the pigeonhole principle, either all values exist exactly once, or a value exists two or more times.



      In the former case, the difference is 1 (for an array larger than 1 element), in the latter case, the result is 0, since then there are two items that are exactly equal.



      We can thus iterate over the array and keep track of the numbers. If a number already exists once, we return 0, otherwise, we return 1, like:



      // only if it holds that for all i, 1 <= arr[i] <= arr.length
      static int findResult(int arr) {
      bool found = new bool[arr.length]
      for(int i = 0; i < arr.length; i++) {
      if(found[arr[i]-1]) {
      return 0;
      } else {
      found[arr[i]-1] = true;
      }
      }
      return 1;
      }


      For a random array that satisfies the condition with n elements, in n!/nn of the cases, it will return 1, and in the other cases, it will return 0, so the average over random input is n!/nn. As n grows larger, it becomes very unlikely that there are no "collisions", and thus, as @YvesDaoust says, the approximation of 0 is very likely.



      Without 1≤xi≤n: O(n log n)



      In case we drop the constraint, we can first sort the array, and in that case, we iterate over consecutive elements:



      static int findResult(int arr) {
      Arrays.sort(arr);
      int dmin = arr[1] - arr[0];
      for(int i = 2; i < arr.length; i++) {
      int d = arr[i] - arr[i-1];
      if(d < dmin) {
      if(d == 0) {
      return 0;
      }
      dmin = d;
      }
      }
      return dmin;
      }






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 11 at 17:00

























      answered Nov 11 at 15:25









      Willem Van Onsem

      141k16132225




      141k16132225








      • 1




        An approximate solution is possible in O(1): return 0. This will be correct in a vast majority of cases ;-)
        – Yves Daoust
        Nov 11 at 15:34








      • 1




        First one will do. since there have be that constraint(1<=arr[i]<=arr.length). It should work. Thanks man! :-)
        – ysoserious9211
        Nov 11 at 15:43






      • 1




        1 micro-optimization in your 2nd approach. You return dmin the moment you come to know it's 0 .
        – vivek_23
        Nov 11 at 16:50






      • 1




        @WillemVanOnsem maybe I miss something but shouldn't the first findResult code should check in the if statement: if (found[arr[i]]) return 0 else found[arr[i]] = true? (Instead of found[i-1])
        – David Winder
        Nov 11 at 16:54






      • 2




        @DavidWinder: I made a mistake, it should be found[arr[i]-1], thanks :)
        – Willem Van Onsem
        Nov 11 at 17:00














      • 1




        An approximate solution is possible in O(1): return 0. This will be correct in a vast majority of cases ;-)
        – Yves Daoust
        Nov 11 at 15:34








      • 1




        First one will do. since there have be that constraint(1<=arr[i]<=arr.length). It should work. Thanks man! :-)
        – ysoserious9211
        Nov 11 at 15:43






      • 1




        1 micro-optimization in your 2nd approach. You return dmin the moment you come to know it's 0 .
        – vivek_23
        Nov 11 at 16:50






      • 1




        @WillemVanOnsem maybe I miss something but shouldn't the first findResult code should check in the if statement: if (found[arr[i]]) return 0 else found[arr[i]] = true? (Instead of found[i-1])
        – David Winder
        Nov 11 at 16:54






      • 2




        @DavidWinder: I made a mistake, it should be found[arr[i]-1], thanks :)
        – Willem Van Onsem
        Nov 11 at 17:00








      1




      1




      An approximate solution is possible in O(1): return 0. This will be correct in a vast majority of cases ;-)
      – Yves Daoust
      Nov 11 at 15:34






      An approximate solution is possible in O(1): return 0. This will be correct in a vast majority of cases ;-)
      – Yves Daoust
      Nov 11 at 15:34






      1




      1




      First one will do. since there have be that constraint(1<=arr[i]<=arr.length). It should work. Thanks man! :-)
      – ysoserious9211
      Nov 11 at 15:43




      First one will do. since there have be that constraint(1<=arr[i]<=arr.length). It should work. Thanks man! :-)
      – ysoserious9211
      Nov 11 at 15:43




      1




      1




      1 micro-optimization in your 2nd approach. You return dmin the moment you come to know it's 0 .
      – vivek_23
      Nov 11 at 16:50




      1 micro-optimization in your 2nd approach. You return dmin the moment you come to know it's 0 .
      – vivek_23
      Nov 11 at 16:50




      1




      1




      @WillemVanOnsem maybe I miss something but shouldn't the first findResult code should check in the if statement: if (found[arr[i]]) return 0 else found[arr[i]] = true? (Instead of found[i-1])
      – David Winder
      Nov 11 at 16:54




      @WillemVanOnsem maybe I miss something but shouldn't the first findResult code should check in the if statement: if (found[arr[i]]) return 0 else found[arr[i]] = true? (Instead of found[i-1])
      – David Winder
      Nov 11 at 16:54




      2




      2




      @DavidWinder: I made a mistake, it should be found[arr[i]-1], thanks :)
      – Willem Van Onsem
      Nov 11 at 17:00




      @DavidWinder: I made a mistake, it should be found[arr[i]-1], thanks :)
      – Willem Van Onsem
      Nov 11 at 17:00












      up vote
      1
      down vote













      I am assuming that the A's are integer, otherwise the condition 1 <= A[i] <= A.len has no relevance.



      Then there is an O(n) solution by using an histogram.




      1. declare an array of counters of size A.length;


      2. count the multiplicities of the elements of A;


      3. scan this histogram to find the closest non-empty bins.





      Note that this solution assumes that only nonzero differences are considered. If zero difference counts, then Willem's answer is better.






      share|improve this answer



























        up vote
        1
        down vote













        I am assuming that the A's are integer, otherwise the condition 1 <= A[i] <= A.len has no relevance.



        Then there is an O(n) solution by using an histogram.




        1. declare an array of counters of size A.length;


        2. count the multiplicities of the elements of A;


        3. scan this histogram to find the closest non-empty bins.





        Note that this solution assumes that only nonzero differences are considered. If zero difference counts, then Willem's answer is better.






        share|improve this answer

























          up vote
          1
          down vote










          up vote
          1
          down vote









          I am assuming that the A's are integer, otherwise the condition 1 <= A[i] <= A.len has no relevance.



          Then there is an O(n) solution by using an histogram.




          1. declare an array of counters of size A.length;


          2. count the multiplicities of the elements of A;


          3. scan this histogram to find the closest non-empty bins.





          Note that this solution assumes that only nonzero differences are considered. If zero difference counts, then Willem's answer is better.






          share|improve this answer














          I am assuming that the A's are integer, otherwise the condition 1 <= A[i] <= A.len has no relevance.



          Then there is an O(n) solution by using an histogram.




          1. declare an array of counters of size A.length;


          2. count the multiplicities of the elements of A;


          3. scan this histogram to find the closest non-empty bins.





          Note that this solution assumes that only nonzero differences are considered. If zero difference counts, then Willem's answer is better.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 11 at 15:32

























          answered Nov 11 at 15:26









          Yves Daoust

          36.3k72559




          36.3k72559






















              up vote
              0
              down vote













              (Adding to the above answers)



              If you need to do this with O(1) extra space, you can use the following trick on the input sequence A:



              for a in A[1...n]:        // a is an element in A; A is 1-indexed; 1 <= a <= n
              if M < A[a % M]:
              return 0
              A[a % M] += M
              return 1


              Here M (> n) is such that M + n doesn't overflow. The trick can be easily modified to use instead an M which is less than -n.



              Caveats:




              1. Requires random (i.e. O(1)) access to the elements of A.

              2. Not cache-friendly.






              share|improve this answer



























                up vote
                0
                down vote













                (Adding to the above answers)



                If you need to do this with O(1) extra space, you can use the following trick on the input sequence A:



                for a in A[1...n]:        // a is an element in A; A is 1-indexed; 1 <= a <= n
                if M < A[a % M]:
                return 0
                A[a % M] += M
                return 1


                Here M (> n) is such that M + n doesn't overflow. The trick can be easily modified to use instead an M which is less than -n.



                Caveats:




                1. Requires random (i.e. O(1)) access to the elements of A.

                2. Not cache-friendly.






                share|improve this answer

























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  (Adding to the above answers)



                  If you need to do this with O(1) extra space, you can use the following trick on the input sequence A:



                  for a in A[1...n]:        // a is an element in A; A is 1-indexed; 1 <= a <= n
                  if M < A[a % M]:
                  return 0
                  A[a % M] += M
                  return 1


                  Here M (> n) is such that M + n doesn't overflow. The trick can be easily modified to use instead an M which is less than -n.



                  Caveats:




                  1. Requires random (i.e. O(1)) access to the elements of A.

                  2. Not cache-friendly.






                  share|improve this answer














                  (Adding to the above answers)



                  If you need to do this with O(1) extra space, you can use the following trick on the input sequence A:



                  for a in A[1...n]:        // a is an element in A; A is 1-indexed; 1 <= a <= n
                  if M < A[a % M]:
                  return 0
                  A[a % M] += M
                  return 1


                  Here M (> n) is such that M + n doesn't overflow. The trick can be easily modified to use instead an M which is less than -n.



                  Caveats:




                  1. Requires random (i.e. O(1)) access to the elements of A.

                  2. Not cache-friendly.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 11 at 18:47

























                  answered Nov 11 at 18:41









                  Arsalan Jumani

                  11




                  11






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53250101%2fis-there-any-way-to-compare-each-element-in-an-array-using-a-single-loop%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Bressuire

                      Vorschmack

                      Quarantine