题目一
打乱数组
给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。打乱后,数组的所有排列应该是 等可能 的。
实现 Solution class:
Solution(int[] nums) 使用整数数组 nums 初始化对象
int[] reset() 重设数组到它的初始状态并返回
int[] shuffle() 返回数组随机打乱后的结果
作者:力扣 (LeetCode)
链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/xn6gq1/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
思路:
从数组的n个下标中随机挑选一个。放到第一个元素。
但是要保证抽到的元素不会在被抽到,把抽到的下标对应的值与数组最后一个元素交换,然后在剩下的n-1个元素中继续抽取。
题解
class Solution {
int[] nums;
int[] original;
public Solution(int[] nums) {
this.nums = nums;
this.original = new int[nums.length];
System.arraycopy(nums,0,original,0,nums.length);
}
public int[] reset() {
System.arraycopy(original,0,nums,0,nums.length);
return nums;
}
public int[] shuffle() {
int[] shuffled = new int[nums.length];
List<Integer> list = new ArrayList<Integer>();
for(int i=0;i<nums.length;i++){
list.add(nums[i]);
}
Random random = new Random();
for(int i=0;i<nums.length;i++){
int j = random.nextInt(list.size());
shuffled[i] = list.remove(j);
}
System.arraycopy(shuffled,0,nums,0,nums.length);
return nums;
}
}
/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(nums);
* int[] param_1 = obj.reset();
* int[] param_2 = obj.shuffle();
*/
class Solution {
int[] nums;
int[] original;
public Solution(int[] nums) {
this.nums = nums;
this.original = new int[nums.length];
System.arraycopy(nums,0,original,0,nums.length);
}
public int[] reset() {
System.arraycopy(original,0,nums,0,nums.length);
return nums;
}
public int[] shuffle() {
Random random = new Random();
for(int i=0;i<nums.length;i++){
int j = i+ random.nextInt(nums.length - i);
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
return nums;
}
}
/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(nums);
* int[] param_1 = obj.reset();
* int[] param_2 = obj.shuffle();
*/
题目二
最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack() 初始化堆栈对象。
void push(int val) 将元素val推入堆栈。
void pop() 删除堆栈顶部的元素。
int top() 获取堆栈顶部的元素。
int getMin() 获取堆栈中的最小元素。
示例 1:
输入:
[“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.
作者:力扣 (LeetCode)
链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/xnkq37/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题解
辅助栈:
栈的特性是先进先出,如果a,b,c,d依次进入,那弹出的顺序也一定是a,b,c,d,如果a在栈里,那b,c,d一定在栈中。
所以借用辅助栈,时刻保持最小值在栈顶,可随时弹出。
- 进栈:
stack直接进栈,辅助栈minstack先判断栈顶和进栈元素值大小,选小的进栈minStack.push(Math.min(minStack.peek(),val));
(这里如果栈顶元素小,那就选栈顶元素再进一次栈,保持着辅助栈和stack元素数量一致)
- 出栈:
stack直接出栈,minstack也直接出栈
- 获取栈顶部元素:
直接stack.peek()
- 获取最小的元素
直接minstack.peek()
class MinStack:
def __init__(self):
self.stack = []
self.min_stack = [math.inf]
def push(self, val: int) -> None:
self.stack.append(val)
self.min_stack.append(min(val,self.min_stack[-1]))
def pop(self) -> None:
self.stack.pop()
self.min_stack.pop()
def top(self) -> int:
return self.stack[-1]
def getMin(self) -> int:
return self.min_stack[-1]
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()
stack.peek()获取栈顶值,只是获取不删除
stack.pop获取栈顶值,并且弹栈(删除栈顶值)
class MinStack {
Deque<Integer> xStack;
Deque<integer> minStack;
public MinStack() {
xStack = new LinkedList<Integer>();
minStack = new LinkedList<Integer>();
minStack.push(Integer.MAX_VALUE);
}
public void push(int val) {
xStack.push(val);
minStack.push(Math.min(minStack.peek(),val));
}
public void pop() {
xStack.pop();
minStack.pop();
}
public int top() {
return xStack.peek();
}
public int getMin() {
return minStack.peek();
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(val);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/