一、用栈实现队列
用两个栈stack1(用于实现入队操作的栈)和stack2(用于实现出队操作的栈)。要实现队列的先进先出,在出队的时候先检查stack2是否为空,将需要出栈的stack1的内容全部压栈到stack2中,然后从stack2实现出队操作。总的来说就是经过stack2“颠倒了一下”。
class MyQueue {
Stack<Integer> stack1;
Stack<Integer> stack2;
public MyQueue() {
stack1=new Stack<Integer>();
stack2=new Stack<Integer>();
}
public void push(int x) {
this.stack1.push(x);
}
public int pop() {
if(this.stack2.empty()){
while(!this.stack1.empty())
this.stack2.push((Integer)this.stack1.pop());
}
return this.stack2.pop();
}
public int peek() {
if(this.stack2.empty()){
while(!this.stack1.empty())
this.stack2.push((Integer)this.stack1.pop());
}
return this.stack2.peek();
}
public boolean empty() {
return stack1.empty()&&stack2.empty();
}
}
二、用队列实现栈
这个需要在压栈的时候设计一下。需要实现栈的后进先出,入栈的时候就得让后面进的排队排到队列的前面。需要借助两个队列queue1和queue2。入队时先将入队元素放到queue2中,再将queue1中的所有元素出队到queue2中,此时在queue2中,后进来的元素就拍到了队首,queue1为空,再将queue2的元素全部出队到queue1中。出栈的时候从queue1中出栈即可。
class MyStack {
Queue<Integer> queue1;
Queue<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());
}
while(!queue2.isEmpty()){
queue1.offer(queue2.poll());
}
}
public int pop() {
return queue1.poll();
}
public int top() {
return queue1.peek();
}
public boolean empty() {
return queue1.isEmpty();
}
}
三、两数之和
借助hash将本来for循环中的查询target-nums[i]这个值是否存在于数组中的时间给优化掉了。所以时间复杂度为O(n)
public int[] twoSum(int[] nums, int target) {
int[] ans=new int[]{-1,-1};
int len=nums.length;
HashMap<Integer,Integer> map=new HashMap<Integer,Integer>();
for(int i=0;i<len;i++){
map.put(nums[i],i);
}
for(int i=0;i<len;i++){
int value=target-nums[i];
if(map.containsKey(value)&&map.get(value)!=i){
ans[0]=i;
ans[1]=map.get(value);
}
}
return ans;
}
四、三数之和
因为要求 答案中不可以包含重复的三元组。所以用哈希会比较麻烦,如果用暴力枚举会是O(n^3)的时间复杂度。为了答案中不可以包含重复的三元组,可以先将数组排序,排序后,先第一个枚举for循环中如果上一个值和当前值相等,则跳过此轮枚举。枚举nums[i],接下来就变成了target=0-nums[i]的“两数之和”问题了。
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
int len=nums.length;
List<List<Integer>> ans=new ArrayList<List<Integer>>();
for(int i=0;i<len;i++){
if(i>0&&nums[i]==nums[i-1])
continue;
int target=0-nums[i];
int left=i+1;
int right=len-1;
while(left<right){
if(nums[left]+nums[right]>target)
right--;
else if(nums[left]+nums[right]<target)
left++;
else if(i!=left&&i!=right&&left!=right){
List<Integer> temp=new ArrayList<Integer>();
temp.add(nums[i]);
temp.add(nums[left]);
temp.add(nums[right]);
ans.add(temp);
left++;
right--;
while(left<len&&nums[left]==nums[left-1])
left++;
while(right>=0&&nums[right]==nums[right+1])
right--;
}
else
left=right;
}
}
return ans;
}