如何在不使用max()或迭代它的情况下在堆栈中查找最大整数值?

时间:2013-07-24 18:02:45

标签: java

我在接受采访时被问到以下问题:如果你有一个整数堆栈,你如何在不使用Collections.max的情况下找到堆栈的最大值,而不是迭代堆栈并比较元素。我用下面的代码回答它,因为我不知道使用任何Collections API或迭代Stack并使用比较的另一种方式。有什么想法吗?

import java.util.Collections;
import java.util.Stack;

public class StackDemo {
    public static void main(String[] args){
        Stack lifo = new Stack();
        lifo.push(new Integer(4));
        lifo.push(new Integer(1));
        lifo.push(new Integer(150));
        lifo.push(new Integer(40));
        lifo.push(new Integer(0));
        lifo.push(new Integer(60));
        lifo.push(new Integer(47));
        lifo.push(new Integer(104));

        if(!lifo.isEmpty()){
            Object max = Collections.max(lifo);
            System.out.println("max=" + max.toString());
        }
    }
}

14 个答案:

答案 0 :(得分:31)

改为使用Collections.min()

if (!lifo.isEmpty()) {
  Integer max = Collections.min(lifo, new Comparator<Integer>() {
    @Override
    public int compare(Integer o1, Integer o2) {
      return o2.compareTo(o1);
    }
  });
  System.out.println("max=" + max.toString());
}

请注意,自定义Comparator会翻转比较,以便Collections.min()实际返回最大值

答案 1 :(得分:11)

import java.util.Collections;
import java.util.Stack;

public class StackDemo {
    public static void main(String[] args) {
        Stack lifo = new Stack();
        lifo.push(new Integer(4));
        lifo.push(new Integer(1));
        lifo.push(new Integer(150));
        lifo.push(new Integer(40));
        lifo.push(new Integer(0));
        lifo.push(new Integer(60));
        lifo.push(new Integer(47));
        lifo.push(new Integer(104));

        System.out.println("max= 150"); // http://xkcd.com/221/
    }
} 

答案 2 :(得分:10)

不确定这是否满足您的问题需求,但这样可以避免使用max()iteration,无论如何sort确实使用iteration和{{1}在背景中。

Comparable

答案 3 :(得分:9)

修改

  

没有遍历堆栈

实际上并不禁止所有迭代。相反,这个问题只禁止做简单的

for (Integer i : lifo)

因此,该解决方案满足了问题的局限性。


只清空堆栈的副本。弹出副本中的每个元素,始终检查max与整数。

Stack<Integer> lifoCopy = (Stack<Integer>) lifo.clone();
int max = Integer.MIN_VALUE;

while (!lifoCopy.isEmpty())
{
    max = Math.max(lifoCopy.pop(), max);
}

System.out.println("max=" + max.toString());

即使您的面试官决定限制更多并且不允许更多内置功能(最大,最小,排序等),这将在O(n)时间内为您工作。

此外,如果您需要让原始版本无损,但无法使用克隆,则可以使用额外的堆栈来执行此操作:

Stack<Integer> reverseLifo = new Stack<Integer>();
int max = Integer.MIN_VALUE;

while (!lifo.isEmpty())
{
    int val = lifo.pop();

    max = Math.max(val, max);

    reverseLifo.push(val);
}

while (!reverseLifo.isEmpty())
{
    lifo.push(reverseLifo.pop());
}

System.out.println("max=" + max.toString());

最后,这假设可以接受与temp变量的比较。如果根本不允许比较,则此解决方案与this method一起使用。

答案 4 :(得分:7)

此代码:

public static Integer max(Stack stack) {
    if (stack.isEmpty()) {
        return Integer.MIN_VALUE;
    }
    else {
        Integer last = (Integer)stack.pop();
        Integer next = max(stack);
        stack.push(last);
        if (last > next) {
            return last;
        }
        else {
            return next;
        }            
    }
}

public static void main(String[] args){
    Stack lifo = new Stack();
    lifo.push(new Integer(4));
    lifo.push(new Integer(1));
    lifo.push(new Integer(150));
    lifo.push(new Integer(40));
    lifo.push(new Integer(0));
    lifo.push(new Integer(60));
    lifo.push(new Integer(47));
    lifo.push(new Integer(104));

    System.out.println(Arrays.deepToString(lifo.toArray()));
    System.out.println(max(lifo));
    System.out.println(Arrays.deepToString(lifo.toArray()));
}

输出:

[4, 1, 150, 40, 0, 60, 47, 104]
150
[4, 1, 150, 40, 0, 60, 47, 104]

它是给定堆栈的递归,找到最大元素并且不更改堆栈顺序。

但是,仅当您define it like that时,迭代与递归不同。另外,为了找到最大值,你必须以某种方式比较所有元素 - 以任何数学形式,与Anirudh showed等关系或按位运算符。恕我直言,相当模糊的任务。

答案 5 :(得分:6)

您可以使用bitwise operator代替..

public int getMax(int a, int b) 
{
    int c = a - b;
    int k = (c >> 31) & 0x1;
    int max = a - k * c;
    return max;
}

现在你可以做到

int max=Integer.MIN_VALUE-1; 
while(!stack.empty())
{
    max=getMax(max,stack.pop());
}

答案 6 :(得分:5)

这可以在O(1)时间和O(n)存储器中完成。 修改push和pop方法(或通过继承使用您自己的扩展标准堆栈)来跟踪另一个堆栈中的当前最大值。

将元素推入堆栈时,将max(currentElem,maxStack.peek())推送到maxStack 当您从堆栈中弹出元素时,也会从最大堆栈中弹出当前最大值。

此解决方案很好地说明了这一点,因此我不会对其进行更多扩展:https://stackoverflow.com/a/3435998/1007845

答案 7 :(得分:4)

时间在盒子外面思考。使用Wolfram Alpha REST API,并要求其计算结果

"maximum of " + Arrays.deepToString(lifo.toArray())

它将return 150

答案 8 :(得分:1)

将元素推入堆栈时,请更新最大值

void main()
    int max = Integer.min
    lifo.push(1)

,而

   void push(Integer value) {
       //push into stack
       //update max value
   }

答案 9 :(得分:1)

您可以使用以下内容将其转换为TreeSet

int myMax = new TreeSet<Integer>(lifo).last();

答案 10 :(得分:1)

将Collections.sort与按降序排序的比较器一起使用,然后从堆栈中查看顶部元素。

答案 11 :(得分:1)

这是我的解决方案:

import java.util.Arrays;
import java.util.Collections;
import java.util.Stack;

public class StackDemo {
    public static void main(String[] args){
        Stack lifo = new Stack();
        lifo.push(new Integer(4));
        lifo.push(new Integer(1));
        lifo.push(new Integer(150));
        lifo.push(new Integer(40));
        lifo.push(new Integer(0));
        lifo.push(new Integer(60));
        lifo.push(new Integer(47));
        lifo.push(new Integer(104));

        Object lifoArray[] = lifo.toArray();
        Arrays.sort(lifoArray);
        System.out.println(lifoArray[lifoArray.length-1]);
    }
}

Arrays.sort()按升序排列,因此排序数组中的最后一个值将是最大值。

答案 12 :(得分:1)

1 x - 将元素x推入堆栈。

2 - 删除堆栈顶部的元素。

3 - 打印堆栈中的最大元素。

    import java.io.*;
    import java.util.*;
    import java.text.*;
    import java.math.*;
    import java.util.regex.*;
    public class Solution {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            Stack <StackItem> st = new Stack <StackItem> ();
            int n = sc.nextInt();//number of choice
            int choice;
            int max = 0;
            for (int i = 0; i<n; i++) {
               choice = sc.nextInt();
               if (choice == 1) {//insert/push an item
                  int newInt = sc.nextInt();
                  if (!st.isEmpty()) {
                      max = st.peek().currentMax;
                  } else {
                      max = 0;
                  }
                  if (newInt > max) {
                        max = newInt;
                  }
                  StackItem item = new StackItem(newInt, max);
                  st.push(item);
                } else if (choice == 2) {//pop
                    if (!st.isEmpty()) st.pop();
                } else if (choice == 3) {//print the maximum item
                    System.out.println(st.peek().currentMax);
                }
            }
        }
    }
    class StackItem {
        int val;
        int currentMax;
        StackItem(int val, int max) {
            this.val = val;
            this.currentMax = max;
        }
    }

答案 13 :(得分:0)

如果没有迭代,您可以进行递归调用。如果不是作业,那么这样做是不合逻辑的。或者你也可以不经迭代地做到这一点。递归。

然而,这里有一个简单快捷的方法:

public class StackDemo {
    public static int max = 0; //set this to least, may be negative
    public static Stack lifo = new Stack();
    public static void main(String[] args){        
        pushToStack(new Integer(4));
        pushToStack(new Integer(1));

        if(!lifo.isEmpty()){
            Object max = Collections.max(lifo);
            System.out.println("max=" + max);
        }
    }
    void static int pushToStack(Integer value){
        lifo.push(value);
        if(max<value){
        max = value;
        }
        return max;
    }    

}