我在接受采访时被问到以下问题:如果你有一个整数堆栈,你如何在不使用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());
}
}
}
答案 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;
}
}