如何在不使用 max() 或对其进行迭代的情况下找到堆栈中的最大整数值?
Posted
技术标签:
【中文标题】如何在不使用 max() 或对其进行迭代的情况下找到堆栈中的最大整数值?【英文标题】:How to Find the Max Integer Value in a Stack without using max() or iterating over it? 【发布时间】:2013-07-24 08:56:10 【问题描述】:我在一次采访中被问到以下问题:如果你有一个整数堆栈,你如何在不使用 Collections.max 并且不遍历堆栈和比较元素的情况下找到堆栈的最大值。我用下面的代码回答了这个问题,因为我不知道除了使用任何 Collections API 或迭代堆栈并使用比较之外的另一种方法。有什么想法吗?
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());
【问题讨论】:
疯狂的远射,但我们应该如何理解“比较元素”?将 an 元素与中间变量进行比较是否仍然计数(即遍历堆栈,保持局部最大值并将每个元素与该最大值进行比较) 如果堆栈刚刚交给您并且您不允许查看内容,我看不到执行此操作的方法。也许答案是“定义一个新的 Stack 子类,在其中覆盖push
操作以更新内部存储的最大值,然后定义 public int max() return this.maxValue;
”?
我建议你先用铅笔和纸用英文写下你需要解决问题的步骤。
@LukeW。只要我的假设认为将单个元素与临时变量进行比较并不构成“比较元素”
我们可以使用 StackSort 吗? xkcd.com/1185(鼠标悬停图片)
【参考方案1】:
编辑:
无需遍历堆栈
实际上并不禁止 all 迭代。相反,这个问题只禁止做简单的事情
for (Integer i : lifo)
因此,此解决方案满足问题的局限性。
只需清空堆栈的副本。从副本中弹出每个元素,同时根据整数检查最大值。
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());
即使你的面试官决定更严格并且不允许更多内置函数(max、min、sort 等),这也会在 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());
最后,这假设与临时变量的比较是可以接受的。如果根本不允许比较,则此解决方案与this method 结合使用即可。
【讨论】:
这不会颠倒堆栈的顺序吗? @LukeW。Stack<Integer> lifoCopy = lifo.clone();
不会编译。
@Nima 使用演员表修复。
这不是“迭代堆栈”吗?
@BenJackson OP 不打算使用for (Integer i : lifo)
。这不是迭代堆栈,而是迭代直到堆栈为空。【参考方案2】:
当你将元素压入堆栈时,更新最大值
void main()
int max = Integer.min
lifo.push(1)
同时
void push(Integer value)
//push into stack
//update max value
【讨论】:
可以假设吗?我相信你只会得到一堆整数。【参考方案3】:您可以将其转换为TreeSet
:
int myMax = new TreeSet<Integer>(lifo).last();
【讨论】:
为什么要在这里声明一个显式比较器? @arshajii 好的。当我真正有时间时,我会编辑它。如果您愿意,请随意进行编辑。【参考方案4】:将 Collections.sort 与按降序排序的 Comparator 一起使用,然后从 Stack 中查看顶部元素。
【讨论】:
我认为 OP 想要保留堆栈。 也许答案至少应该提到这一点。【参考方案5】:改用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()
实际上会返回最大值。
【讨论】:
是的,有趣的设计考虑。 我不确定这是否符合挑战精神,但我喜欢实施:D @HenryKeiter 你可能是对的,但我不能放弃成为聪明人的机会! 如果这不是一个令人讨厌的问题,我会说这是一个令人讨厌的答案......但在上下文中,它是完美的。【参考方案6】:无需迭代,您就可以进行递归调用。如果这不是家庭作业,那么这样做是不合逻辑的。或者,您也可以在没有迭代和递归的情况下执行此操作。
但是这里有一个快速且简单的方法:
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;
【讨论】:
这应该是递归的吗? 不,不是。它只是一个不使用 max() 的非迭代解决方案;【参考方案7】:不确定这是否能满足您的问题需求,但可以避免使用max()
和iteration
,无论如何sort
确实在后台使用iteration
和Comparable
。
if (!lifo.isEmpty())
Stack sc = (Stack) lifo.clone();
Collections.sort(sc);
System.out.println("max=" + sc.get(sc.size() - 1));
【讨论】:
我猜这就是答案 对不起,我被要求不要使用 Collections.sort @Smit Collections.sort() 也在后台使用比较。 @c12 你的问题应该反映这一点。 @Juvanis 感谢您的提醒。让我更新答案。和@c12 我同意@LukeW。【参考方案8】:你可以改用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());
【讨论】:
有效,但会破坏堆栈。 +1getMax
功能。如果需要维护堆栈,您需要clone()
或维护另一个堆栈,正如我在回答中讨论的那样。
@LukeW。您可以通过递归避开两个堆栈。看我的回答。我认为 anirudh 的比较和我的递归形成了答案。当然,除非“维护堆栈”是指不弹出/推送它的元素?
@linski 没错,但我提供的额外堆栈解决方案不是迭代的,无论您如何定义递归。
@LukeW。我不同意。来自wikipedia 的更广泛定义:“计算中的迭代是计算机程序中语句块的重复。”那就是所有的循环和递归。这就是我认为任务定义模糊的原因。【参考方案9】:
这可以在 O(1) 时间和 O(n) 内存中完成。 修改 push 和 pop 方法(或通过继承扩展您自己的标准堆栈)以跟踪另一个堆栈中的当前最大值。
当你将元素压入堆栈时,将 max(currentElem, maxStack.peek()) 压入 maxStack 当您从堆栈中弹出元素时,也从您的最大堆栈中弹出当前最大值。
这个解决方案很好地说明了它,所以我不会对此进行更多扩展:https://***.com/a/3435998/1007845
【讨论】:
我想这一定是正确的答案。取缔“迭代”听起来像是 O(1) 获取最大值的代码,只能使用特殊的数据结构来完成,而不是通用的java.util.Stack
【参考方案10】:
这段代码:
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。恕我直言,定义非常模糊的任务。
【讨论】:
我同意这个问题的含糊之处。有些术语需要在上下文中明确定义,才能解决。【参考方案11】:是时候跳出框框思考了。使用Wolfram Alpha REST API,并要求它计算以下的结果:
"maximum of " + Arrays.deepToString(lifo.toArray())
它将return 150。
【讨论】:
【参考方案12】: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/
【讨论】:
【参考方案13】:这是我的解决方案:
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()
按升序排列,所以排序后的数组中的最后一个值为最大值。
【讨论】:
【参考方案14】: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;
【讨论】:
以上是关于如何在不使用 max() 或对其进行迭代的情况下找到堆栈中的最大整数值?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 R/Python 中迭代/循环一个大型(>2GB)JSON 数据集? [复制]