Leetcode | 155. 最小栈(java实现)

本文介绍了如何设计一个最小栈,该栈支持push、pop、top和getMin操作,并能在常数时间内检索到最小元素。通过分析题目,提出使用两个栈同步操作的解题思路,其中一个栈用于存储最小值。此外,还探讨了一种优化方案,即只在遇到更小值时才更新辅助栈。最后,介绍了一种仅使用一个栈和额外变量的实现方法,利用栈来保存不同最小值阶段的标记。
摘要由CSDN通过智能技术生成

题目

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
 push(x) —— 将元素 x 推入栈中。
 pop() —— 删除栈顶的元素。
 top() —— 获取栈顶元素。
 getMin() —— 检索栈中的最小元素。
示例:
输入:
 [“MinStack”,“push”,“push”,“push”,“getMin”,“pop”,“top”,“getMin”]
 [  [],   [-2],  [0], [-3],  [],   [],  [],  []  ]
输出:
 [null,null,null,null,-3,null,0,-2]
解释:
 MinStack minStack = new MinStack();
 minStack.push(-2);
 minStack.push(0);
 minStack.push(-3);
 minStack.getMin(); --> 返回 -3.
 minStack.pop();
 minStack.top(); --> 返回 0.
 minStack.getMin(); --> 返回 -2.
提示:pop、top 和 getMin 操作总是在 非空栈 上调用。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/min-stack

解题

题目分析

 乍一看这题输入输出没看懂,其实很简单,就是设计一个栈类叫最小栈,和普通栈(java自带的stack类)的区别就在于多了一个可以返回当前栈内最小值的getMin()方法。Stack栈类的其他方法照常可以使用。我们的主要问题就是求解怎么在常数时间检索出当前栈内所有元素的最小值。
 对于一个最小栈minStack来说,题目中要求的四个方法:

  1. 入栈方法:push(x),和Stack类的入栈方法一样,可以直接用stack.push(x)实现
  2. 出栈方法:pop() ,和Stack类的出栈方法一样,可以直接用stack.pop()实现。
  3. 获取栈顶元素方法:top(),Stack类同样有类似的方法peek(),peek()和pop()的去区别在于两者都能返回栈顶元素的值,但是pop()会同时删除栈顶元素,peek()不删。
  4. 检索栈中的最小元素方法:getMin(),只有此方法原本的Stack类中没有,我们需要设计实现。

两个栈实现(创建一个辅助栈存储最小值)

 我们可以在minStack栈内用两个栈来实现存储当前栈内的最小值。
 一个栈stack为普通的栈,依次存储我们压入栈的值。
 另一个栈stackmin和上个栈同等大小,同步上一个栈的所有操作,一一对应,只不过存储的是栈stack中对应元素作为栈顶元素时的当前stack栈内元素的最小值,这个栈作为一个辅助栈。
 如何存储?因为两个栈同步,我们维护一个当前最小值的变量,所以每当stack栈中加入一个元素,与之前维护的最小值变量相比,如果比之前的小就更新最小值变量,如果没之前那个小就维护之前那个值将其压入stackmin栈中。
 这样我们在minStack类中的getMin()方法中只需将当前的minStack栈中的栈顶元素弹出即可。比如示例中输入的意思其实是,先构造一个minStack,然后依次压入push值-2、0、-3,然后获取当前栈内的最小值。当前的两个栈内元素如下图解:(所以当前栈内元素最小值是-3)
 在这里插入图片描述
 然后我们弹出一个栈顶元素的话,两个栈都同步弹出栈顶元素。两个栈更新如下图:(那么此时栈内元素的最小值就变为-2了)
在这里插入图片描述

class MinStack {
   
    public Stack<Integer> stack;
    public Stack<Integer> stackmin;
    /** initialize your data structure here. */
    public MinStack() {
   
        stack = new Stack<>();
        stackmin = new Stack<>();
    }
    
    
### 回答1: 可以使用Java中的排序功能来实现。可以使用Arrays.sort()函数,将列表中的元素按照字母顺序排序,或者使用Collections.sort()函数,将列表中的元素按用户指定的排序规则排序。 ### 回答2: 为了实现LeetCode 2561题(Rearranging Fruits)的要求,需要使用Java编程语言。主要思路是遍历给定的水果数组,同时用一个哈希表来记录每个水果出现的次数。然后根据题目要求,重新排列水果使得相同类型的水果尽可能接近,并且按照出现次数的非递增顺序排序。 具体实现步骤如下: 1. 创建一个HashMap来存储每个水果的出现次数。遍历给定的水果数组,如果该水果已经存在于HashMap中,则将其出现次数加1;否则,将该水果添加到HashMap,并将其出现次数初始化为1。 2. 创建一个ArrayList来存储已经排列好的水果。通过HashMap的entrySet方法获取到每种水果和它的出现次数,然后将这些entry按照出现次数的非递增顺序进行排序。 3. 遍历排序好的entry集合,根据每个水果的出现次数,在ArrayList中连续添加相应数量的水果。 4. 返回排列好的水果数组。 以下是Java代码的示例实现: ```java import java.util.*; class Solution { public String[] rearrange(String[] fruits) { HashMap<String, Integer> fruitCountMap = new HashMap<>(); // 统计每个水果的出现次数 for (String fruit : fruits) { if (fruitCountMap.containsKey(fruit)) { fruitCountMap.put(fruit, fruitCountMap.get(fruit) + 1); } else { fruitCountMap.put(fruit, 1); } } ArrayList<Map.Entry<String, Integer>> sortedEntries = new ArrayList<>(fruitCountMap.entrySet()); // 根据出现次数进行非递增排序 Collections.sort(sortedEntries, new Comparator<Map.Entry<String, Integer>>() { public int compare(Map.Entry<String, Integer> entry1, Map.Entry<String, Integer> entry2) { return entry2.getValue().compareTo(entry1.getValue()); } }); ArrayList<String> rearrangedFruits = new ArrayList<>(); // 根据出现次数连续添加水果 for (Map.Entry<String, Integer> entry : sortedEntries) { String fruit = entry.getKey(); int count = entry.getValue(); for (int i = 0; i < count; i++) { rearrangedFruits.add(fruit); } } return rearrangedFruits.toArray(new String[0]); } } ``` 使用以上代码,可以对给定的水果数组进行重新排列,使得相同类型的水果尽可能接近,并且按照出现次数的非递增顺序进行排序。返回的结果就是排列好的水果数组。 ### 回答3: 题目要求将一个字符串中的水果按照特定规则重新排列。我们可以使用Java实现这个问题。 首先,我们需要定义一个函数来解决这个问题。 ```java public static String rearrangeFruits(String fruits) { // 将字符串转换为字符数组方便处理 char[] fruitArray = fruits.toCharArray(); // 统计每种水果的数量 int[] fruitCount = new int[26]; for (char fruit : fruitArray) { fruitCount[fruit - 'a']++; } // 创建一个新的字符数组来存储重新排列后的结果 char[] rearrangedFruitArray = new char[fruitArray.length]; // 逐个将水果按照规则放入新数组中 int index = 0; for (int i = 0; i < 26; i++) { while (fruitCount[i] > 0) { rearrangedFruitArray[index++] = (char) ('a' + i); fruitCount[i]--; } } // 将字符数组转换为字符串并返回 return new String(rearrangedFruitArray); } ``` 上述代码中,我们首先将字符串转换为字符数组,并使用一个长度为26的数组来统计每一种水果的数量。然后,我们创建一个新的字符数组来存储重新排列后的结果。 接下来,我们利用双重循环将每一种水果按照规则放入新数组中。最后,我们将字符数组转换为字符串并返回。 例如,如果输入字符串为`"acbba"`,则经过重新排列后,输出结果为`"aabbc"`。 这样,我们就用Java实现了题目要求的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值