用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
示例 1:
输入:
["CQueue","appendTail","deleteHead","deleteHead"]
[[],[3],[],[]]
输出:[null,null,3,-1]
示例 2:
输入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
输出:[null,-1,null,null,5,2]
维护两个栈,第一个栈支持插入操作,第二个栈支持删除操作。
java:
class CQueue { Deque<Integer> stack1; Deque<Integer> stack2; public CQueue() { stack1 = new LinkedList<Integer>(); stack2 = new LinkedList<Integer>(); } public void appendTail(int value) { stack1.push(value); } public int deleteHead() { // 如果第二个栈为空 if (stack2.isEmpty()) { while (!stack1.isEmpty()) { stack2.push(stack1.pop()); } } if (stack2.isEmpty()) { return -1; } else { int deleteItem = stack2.pop(); return deleteItem; } } }
C++:
class CQueue { Deque<Integer> stack1; Deque<Integer> stack2; public CQueue() { stack1 = new LinkedList<Integer>(); stack2 = new LinkedList<Integer>(); } public void appendTail(int value) { stack1.push(value); } public int deleteHead() { // 如果第二个栈为空 if (stack2.isEmpty()) { while (!stack1.isEmpty()) { stack2.push(stack1.pop()); } } if (stack2.isEmpty()) { return -1; } else { int deleteItem = stack2.pop(); return deleteItem; } } }
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例 1:
输入:head = [1,2,2,1]
输出:true
示例 2:
输入:head = [1,2]
输出:false
通过快慢指针找到中心节点,再进行链表的反转。
具体代码如下:
public boolean isPalindrome(ListNode head) { ListNode fast = head, slow = head; //通过快慢指针找到中点 while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; } //如果fast不为空,说明链表的长度是奇数个 if (fast != null) { slow = slow.next; } //反转后半部分链表 slow = reverse(slow); fast = head; while (slow != null) { //然后比较,判断节点值是否相等 if (fast.val != slow.val) return false; fast = fast.next; slow = slow.next; } return true; } //反转链表 public ListNode reverse(ListNode head) { ListNode prev = null; while (head != null) { ListNode next = head.next; head.next = prev; prev = head; head = next; } return prev; }
我们知道栈是先进后出的一种数据结构,这里还可以使用栈先把链表的节点全部存放到栈中,然后再一个个出栈,这样就相当于链表从后往前访问了,通过这种方式也能解决
public boolean isPalindrome(ListNode head) { ListNode temp = head; Stack<Integer> stack = new Stack(); //把链表节点的值存放到栈中 while (temp != null) { stack.push(temp.val); temp = temp.next; } //然后再出栈 while (head != null) { if (head.val != stack.pop()) { return false; } head = head.next; } return true; }
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
方法一:哈希表
public boolean hasCycle(ListNode head) { Set<ListNode> set = new HashSet<>(); while (head != null) { //如果重复出现说明有环 if (set.contains(head)) return true; //否则就把当前节点加入到集合中 set.add(head); head = head.next; } return false; }
方法二:快慢指针
public class solution{ public boolean hasCycle(ListNode head){ if(head == null || head.next == null){ return false; } ListNode slow = head; ListNode fast = head.next; while(slow != fast){ if(fast == null || fast.next == null){ return false; } slow = slow.next; fast = fast.next.next; } return true; } }