1.用栈实现队列
/**
* 用栈实现队列
* LeetCode232 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
* 实现 MyQueue 类:
* void push(int x) 将元素 x 推到队列的末尾
* int pop() 从队列的开头移除并返回元素
* int peek() 返回队列开头的元素
* boolean empty() 如果队列为空,返回 true ;否则,返回 false
* 方法 :每次pop 或 peek 时,若输出栈为空则将输入栈的全部数据依次弹出并压入输出栈
* 这样输出栈从栈顶往栈底的顺序就是队列从队首往队尾的顺序
*/
class MyQueue {
Deque<Integer> inStack;
Deque<Integer> outStack;
public MyQueue() {
inStack = new LinkedList<Integer>();
outStack = new LinkedList<Integer>();
}
public void push(int x) {
inStack.push(x);
}
public int pop() {
if(outStack.isEmpty()){
in2out();
}
return outStack.pop();
}
public int peek() {
if(outStack.isEmpty()){
in2out();
}
return outStack.peek();
}
public boolean empty() {
return inStack.isEmpty() && outStack.isEmpty();
}
public void in2out(){
while(!inStack.isEmpty()){
outStack.push(inStack.pop());
}
}
}
2.用队列实现栈
/**
* 队列实现栈
* LeetCode225 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)
* 实现 MyStack 类:
* void push(int x) 将元素 x 压入栈顶。
* int pop() 移除并返回栈顶元素。
* int top() 返回栈顶元素。
* boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
* 方法 :入栈操作时,首先将元素入队到 queue2,然后将 queue1 的全部元素依次出队并入队到queue2
* 再将 queue1 和 queue2 互换,则 queue1 的元素即为栈内的元素,queue 1的前端和后端分别对应栈顶和栈底
*/
class MyStack {
Deque<Integer> queue1;
Deque<Integer> queue2;
public MyStack() {
queue1 = new LinkedList<Integer>();
queue2 = new LinkedList<Integer>();
}
public void push(int x) {
queue2.offer(x);
while(!queue1.isEmpty()){
queue2.offer(queue1.poll());
}
Deque<Integer> temp;
temp = queue1;
queue1 = queue2;
queue2 = temp;
}
public int pop() {
return queue1.poll();
}
public int top() {
return queue1.peek();
}
public boolean empty() {
return queue1.isEmpty();
}
}
3.两数之和
/**
* LeetCode1.给定一个整数数组 nums 和一个整数目标值 target,
* 请你在该数组中找出 和为目标值 target 的那两个整数,并返回它们的数组下标。
* 方法 : 创建一个哈希表,对于每一个 x,首先查询哈希表中是否存在 target - x,
* 然后将 x 插入到哈希表中,即可保证不会让 x 和自己匹配
*
*/
public class TwoSum {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> hashtable = new HashMap<Integer,Integer>();
for(int i = 0 ; i < nums.length; i++){
if(hashtable.containsKey(target - nums[i])){
return new int[]{hashtable.get(target - nums[i]),i};
}
hashtable.put(nums[i],i);
}
return new int[0];
}
}
4.三数之和
/**
* 三数之和
* LeetCode15
* 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?
* 请你找出所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。
* 示例1:
* 输入:nums = [-1,0,1,2,-1,-4]
* 输出:[[-1,-1,2],[-1,0,1]]
* 先将数组排序来处理重复结果,然后固定一位元素
* 由于数组是排好序的,所以用双指针来不断寻找即可求解
*/
public class ThreeSum {
public List<List<Integer>> threeSum(int[] nums) {
int n = nums.length;
Arrays.sort(nums);
// 枚举 a
List<List<Integer>> ans = new ArrayList<List<Integer>>();
for(int first = 0 ; first < n ; ++first){
// 需要和上一次枚举的数不相同
if(first > 0 && nums[first] == nums[first-1]){
continue;
}
// c 对应的指针初始指向数组的最右端
int third = n - 1;
int target = -nums[first];
// 枚举 b
for(int second = first + 1;second < n; ++second){
// 需要和上一次枚举的数不相同
if(second > first + 1 && nums[second] == nums[second-1]){
continue;
}
// 需要保证 b 的指针在 c 的指针的左侧
while(second<third && nums[second] + nums[third]>target){
--third;
}
// 如果指针重合,随着 b 后续的增加
// 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
if(second == third){
break;
}
if(nums[second]+nums[third] == target){
List<Integer> list = new ArrayList<Integer>();
list.add(nums[first]);
list.add(nums[second]);
list.add(nums[third]);
ans.add(list);
}
}
}
return ans;
}
}