栈、队列、哈希
232.用栈实现队列
用两个栈实现先进先出队列。stackA,stackB
入队:元素入栈stackA,stackB不作为存储
出队:将stackA所有元素出栈,stackA出栈元素作为stackB入栈元素,stackB的栈顶元素即为要出队的元素
这边出现一个问题,要去复习Deque和LinkedList的继承关系这方面内容
class MyQueue {
Deque<Integer> stackA;
Deque<Integer> stackB;
public MyQueue() {
stackA = new LinkedList<Integer>();
stackB = new LinkedList<Integer>();
}
public void push(int x) {
stackA.push(x);
}
public int pop() {
while(!stackA.isEmpty()) {
stackB.push(stackA.pop());
}
int ans = stackB.pop();
while(!stackB.isEmpty()) {
stackA.push(stackB.pop());
}
return ans;
}
public int peek() {
while(!stackA.isEmpty()) {
stackB.push(stackA.pop());
}
int ans = stackB.peek();
while(!stackB.isEmpty()) {
stackA.push(stackB.pop());
}
return ans;
}
public boolean empty() {
return stackA.isEmpty();
}
}
225.队列实现栈
class MyStack {
Queue<Integer> que1;
Queue<Integer> que2;
public MyStack() {
que1 = new LinkedList<Integer>();
que2 = new LinkedList<Integer>();
}
//que1:1->2->3,push(4),按照栈应该变成4->1->2->3
//que2:4,将4加入队列2
//que2:4->1->2->3,将que1依次加入que2,此时que1空了
//que1和que2互换
//可以用物理方式模拟一下,蛮简单的
public void push(int x) {
que2.offer(x);
while(!que1.isEmpty()) {
que2.offer(que1.poll());
}
Queue<Integer> temp = que1;
que1 = que2;
que2 = temp;
}
public int pop() {
return que1.poll();
}
public int top() {
return que1.peek();
}
public boolean empty() {
return que1.isEmpty();
}
}
1.两数之和
这题第一反应就是暴力双重循环,就不演示了
这题可以使用hash,将所有数都加入hash,然后遍历数字n,查找hash中是否存在target-n,如果存在,则返回下标。此处下标需要模拟一下,用HashMap的键值对,键为数组元素(元素不重复),值为下标
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<>();
int len = nums.length;
for(int i = 0; i < len; i++) {
if(map.containsKey(target - nums[i])) {//存在对应的值
return new int[]{map.get(target - nums[i]), i};//返回两个下标
}
map.put(nums[i], i);
}
return new int[0];
}
15.三数之和
public List<List<Integer>> threeSum(int[] nums) {
int n = nums.length;
Arrays.sort(nums);
List<List<Integer>> ans = new ArrayList<List<Integer>>();
//在数组中找a,b,c,使得a+b+c = 0
//a = nums[i], b = nums[left], c = nums[right]
//其中i从0开始, left从i + 1开始, right从数组尾部开始
for(int i = 0; i < n; i++) {
//枚举的a与上一次不能相同
if(i > 0 && nums[i - 1] == nums[i]) {
continue;
}
//left与right不相撞
int left = i + 1;
int right = n - 1;
while(left < right) {
if(nums[i] + nums[left] + nums[right] == 0) {
List<Integer> list = new ArrayList<Integer>();
list.add(nums[i]);
list.add(nums[left]);
list.add(nums[right]);
ans.add(list);
// 跳过重复的元素
while (left < right && nums[left] == nums[left + 1]) {
left++;
}
while (left < right && nums[right] == nums[right - 1]) {
right--;
}
left++;
right--;
continue;
}
//这是排序好的nums数组,递增
//如果三者相加小于零,则说明要增大某个值,即增大nums[left]
//即left++;
if(nums[i] + nums[left] + nums[right] < 0) {
left++;
continue;
}
//如果三者相加大于零,说明要减小某个值,即减小nums[right]
//即right--
if(nums[i] + nums[left] + nums[right] > 0) {
right--;
continue;
}
}
}
return ans;
}