5

So ... I have : int array[] = {-8,2,0,5,-3,6,0,9};

I want to find the smallest positive number ( which in the list above is 2 )

This is what i am doing :


int array[] = {-8,2,0,5,-3,6,0,9};

int smallest=0;


        for(int i=0;i<array.length;i++) // Find the first number in array>0 (as initial           
                                         // value for int smallest)
        {
            if(array[i]>0)
            {
                smallest=array[i]; 
                break;// Break out of loop, when you find the first number >0
            }   
        }


        for(int i=0;i<array.length;i++) // Loop to find the smallest number in array[]
        {

            if(smallest>array[i]&&array[i]>0)
            {
                smallest=array[i];

            }

        }

        System.out.println(smallest);

        }

My question is :

Can we reduce the number of steps ? Is there any smarter/shorter way of doing it, with no other data structure.

Thanks.

Jens
  • 67,715
  • 15
  • 98
  • 113
Navchetan
  • 153
  • 1
  • 2
  • 11

11 Answers11

6

is there any smarter/shorter way of doing it?

If you want shorter, with Java 8, you can use a stream of ints:

int min = Arrays.stream(array).filter(i -> i >= 0).min().orElse(0);

(assuming you are happy with a min of 0 when the array is empty).

assylias
  • 321,522
  • 82
  • 660
  • 783
  • 1
    so much overhead for a so simple task – Alex Salauyou Aug 26 '14 at 07:49
  • How do you handle the only positive numebrs limiation without adding a filter, which practically means another iteration? – amit Aug 26 '14 at 08:51
  • @assylias Is it optimized to overcome the slow-down of multiple iterations? – amit Aug 26 '14 at 09:07
  • @amit there will only be one iteration. – assylias Aug 26 '14 at 09:16
  • @assylias Really? I am not fluent in java8, but I figured out it will create a stream of all elements that match the filter condition, and than iterate them to yield the min. Nice to know it is optimized to do it in a single iteration. Is it implementation detail or written in specification? (Not sarcastic comment, truly am impresses) – amit Aug 26 '14 at 09:18
  • 1
    @amit it is by [specification](http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html): *"Laziness-seeking. Many stream operations, such as filtering [...] can be implemented lazily, exposing opportunities for optimization. For example, "find the first String with three consecutive vowels" need not examine all the input strings. Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. **Intermediate operations are always lazy**."*. See also http://stackoverflow.com/a/21223645/829571. – assylias Aug 26 '14 at 09:22
  • @SashaSalauyou on my machine, the stream version takes respectively 65, 200 and 50000 nanoseconds for arrays of 10, 100, 10000 elements, vs. 20, 125, 48000 for the "manual" version. So there is an overhead but it is not very high and decreases in % as the size of the array increases. – assylias Aug 26 '14 at 10:33
5

You do not need to have smallest=array[i], just initialize a variable with INTEGER.MAX_VALUE or array[0] and iterate over the array comparing the value with this variable.

This is achieved in O(n) time and O(1) space and thats the best you can get! :)

a simpler way would be

 int[] array ={-1, 2, 1};
 boolean max_val_present = false;  

 int min = Integer.MAX_VALUE;

 for(int i=0;i<array.length;i++) // Loop to find the smallest number in array[]
 {
      if(min > array[i] && array[i] > 0)
         min=array[i];
      //Edge Case, if all numbers are negative and a MAX value is present
      if(array[i] == Integer.MAX_VALUE)
        max_val_present = true;
 }

 if(min == Integer.MAX_VALUE && !max_val_present) 
 //no positive value found and Integer.MAX_VALUE 
 //is also not present, return -1 as indicator
    return -1; 

 return min; //return min positive if -1 is not returned
NoobEditor
  • 15,563
  • 19
  • 81
  • 112
  • You still return an INTEGER.MAX_VALUE when all items are non-positive. – Seyf Aug 26 '14 at 07:34
  • @SeyfülislamÖzdemir : good point, updated code..thanks fella! :) – NoobEditor Aug 26 '14 at 07:38
  • Now you return -1 when the input is an array which contains only non-positive numbers and at least one INTEGER.MAX_VALUE. You should return an INTEGER.MAX_VALUE for such a case. :) – Seyf Aug 26 '14 at 07:40
  • @SeyfülislamÖzdemir : Edge cases.. :) updated code, validate now! :) – NoobEditor Aug 26 '14 at 07:47
  • Why min <= array[i]? If min == array[i] there is no point of assign min=array[i]. I would change it with min < array[i]. – holap Aug 26 '14 at 07:57
  • Still it won't work. "min <= array[i]" is wrong. It will return 2 for the array [-1, 2, 1]. If you make it >= the function will return -1. :) – Seyf Aug 26 '14 at 07:57
  • Have you tested your code with an array like this? `{8,2,0,5,-3,6,0,9}` ? – gkrls Aug 26 '14 at 08:16
  • Your edit is wrong. You cannot initialize `array[0]` as the initial `smallest`, since it might be negative. (Please revert and downvote will be removed) – amit Aug 26 '14 at 08:52
  • @amit : reverted back to original logic, updated and it works..mind taking back the downvote?? :) – NoobEditor Aug 26 '14 at 09:02
  • @SeyfülislamÖzdemir : updated and its working well... ;) – NoobEditor Aug 26 '14 at 09:04
  • Think it works now. :) If it does not, in case, I don't check as you wouldn't handle one more comment which tells you your errors. :P – Seyf Aug 26 '14 at 10:00
  • @SeyfülislamÖzdemir : nope..its works now...i checked...if u find a bug, most welcome to let me know!! :) – NoobEditor Aug 26 '14 at 10:30
3

Without any prioe knowledge there is no way to avoid iterating the entire array.

You can however make sure you iterate it only once by removing the first loop, and instead just assign smallest = Integer.MAX_VALUE. You can also add a boolean that indicates the array was changed to distinguish between cases where there is no positive integer, and cases where the only positive integer is Integer.MAX_VALUE

amit
  • 175,853
  • 27
  • 231
  • 333
  • 1
    50sec behind...i am getting old!! :) – NoobEditor Aug 26 '14 at 07:26
  • Wondering who downvoted this answer. Please provide a comment why this answer is wrong. – amit Aug 26 '14 at 08:24
  • not really sure who downvoted you..but may be lack of code might be reason (*i too hate those kind of visitors*) :) – NoobEditor Aug 26 '14 at 09:05
  • @NoobEditor I really prefer words over code in many situations, as it lets the OP understand the answer, and implement it by his own. I hope this is not the issue :| – amit Aug 26 '14 at 09:09
1

You don't need two loops for this purpose.

int smallest = Integer.MAX_VALUE; 

for(int i=0;i<array.length;i++) {
    if(array[i] > 0 && smallest > array[i])
    {
        smallest = array[i]; 
    }  
} 

The only problem with this code is that after the loop you can't know that whether all elements are non-positive or at least one of them is Integer.MAX_INT and remaining is non-positive. You should add controls if you think that such a case is possible.

Seyf
  • 889
  • 8
  • 16
0

A sample for you:

    int array[] = {-8,2,0,5,-3,6,0,9};
    int minPosNum = Integer.MAX_VALUE;
    for (int i = 0; i < array.length; i++) {
        if(array[i] > 0 && array[i] < minPosNum){
            minPosNum = array[i];
        }
    }
    System.out.println(minPosNum);
Laurence Geng
  • 424
  • 3
  • 9
0
int array[] = {-8,2,0,5,-3,6,0,9};
int minPos = Integer.MAX_VALUE;

for (int number : array) {
    if (number > 0)
        minPos = Math.min(number, minPos);
}
Michael Kleimann
  • 502
  • 2
  • 10
0

You can try this to do it with 1 loop:

int array[] = {8,2,0,5,-3,6,0,9};
int smallestPositive = array[0];

for(int i = 1; i < array.length; i++){
    if(smallestPositive > 0){
        if(array[i] < smallestPositive && array[i] > 0)
            smallestPositive = array[i];
    }else
        smallestPositive = array[i];
}

System.out.println(smallestPositive); will print 2

gkrls
  • 2,618
  • 2
  • 15
  • 29
0

You can try the following code

import java.util.*;
public class SmallItem 
{
    public static void main(String args[])
    {
       int array[] = {-8,2,0,5,-3,6,0,9};
       int number = Integer.MAX_VALUE;
       ArrayList al = new ArrayList();

       //Here we add all positive items into a ArrayList al
       for(int i=1;i<array.length;i++){
           if(array[i]>0){
               al.add(new Integer(array[i]));
           }
       }

       Iterator it = al.iterator();
       while(it.hasNext()){
           int n = ((Integer)it.next()).intValue();
           if(n<number){
               number = n;
            }
        }
       System.out.println("Smallest number : " + number);
    }
}
Aditya
  • 1,214
  • 7
  • 19
  • 29
0

For C++

int smallest (int array[]){
    int a;
    for(int i=0;i<n;i++){
        if(array[i]>0){
            a=array[i];
            break;
        }
    }

    for (int i=0; i<n; i++){
        if(array[i]<=a && array[i]>0){

            a=array[i];
        }
    }

    return a;
}
bhavya
  • 1
  • 2
0

In JavaScript

var inputArray = [-1,2,1,5,-20];
var arrayWithOnlyPositiveValue = [];

    for(var i=0;i<inputArray.length;i++){

        if(inputArray[i]>=0){
            arrayWithOnlyPositiveValue.push(inputArray[i])
            }

    }

    var min_of_array = Math.min.apply(Math, arrayWithOnlyPositiveValue);
    console.log('---smallestPositiveValue----',min_of_array);
Vic Key
  • 37
  • 4
0
namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] array = { -1, 2, 1, -2, 11, 23, 44 };
            int min = MinArray(array);
            Console.WriteLine(min.ToString() + " is the minimum number!");
            Console.ReadKey();
        }
        public static int MinArray(int[] array)
        {
            int minimumNumber = Int32.MaxValue;
            foreach (int i in array)
            {
                if (i < minimumNumber && i > 0)
                {
                    minimumNumber = i;
                }

            }

            return minimumNumber;
        }
    }
}
Thewads
  • 4,953
  • 11
  • 55
  • 71
Gaurav Tyagi
  • 958
  • 6
  • 10