文章目录
- 两个链表的第一个重合节点
- 判断回文链表
两个链表的第一个重合节点
同LeetCode 160.相交链表
解法一:Hash和Set(集合),此处用Set合适。
把其中一个链表的所有节点引用放入set,再从头遍历另一个链表第一次重合的地方就是答案。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {Set<ListNode> set = new HashSet<>();while(headA != null){set.add(headA);headA = headA.next;}while(headB != null){if(set.contains(headB)) return headB;headB = headB.next;}return null;
}
解法二:使用栈
两个链表都分别入栈,出栈的时候判断最后一个相同引用。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {Stack<ListNode> stackA = new Stack<>();Stack<ListNode> stackB = new Stack<>();while (headA != null) {stackA.push(headA);headA = headA.next;}while (headB != null) {stackB.push(headB);headB = headB.next;}ListNode cur = null;while (!stackA.isEmpty() && !stackB.isEmpty()) {if (stackA.peek() == stackB.peek()) {cur = stackA.pop();stackB.pop();} else break;}return cur;
}
前两种解法利用了数据结构的特点,下面两种则是将两个链表的长度设法弄成一样的,之后节点映射对比。
解法三:拼接
如图AB两个链表如果有重合部分,则可以把AB链表分成 left 和 right 部分,易知 right_a = right_b 。将AB两个链表按照AB、BA两种方式拼接得到的结果可以看到有重合部分,这样两个链表长度相等,则可以映射对比。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if(headA==null || headB==null) return null;ListNode node1 = headA;ListNode node2 = headB;while (node1 != node2){node1 = node1.next;node2 = node2.next;if(node1 == node2) break;// 因为两个合并链表长度一定相等,也就是说遍历完合并链表一定能得到答案。这个判断是对AB链表无交集情况的判断,防止死循环。if (node1!=node2) { if(node1==null) node1 = headB;if(node2==null) node2 = headA;}}return node1;}
解法四:消余
同思路三都是让链表长度相等再遍历。这个方法就是让长的链表遍历到和短链表长度相等时比较。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if(headA==null || headB==null) return null;ListNode node1 = headA;ListNode node2 = headB;int l1 = 0, l2 = 0;while (node1!=null){l1++;node1 = node1.next;}while (node2!=null){l2++;node2 = node2.next;}int l = Math.abs(l1-l2);if(l1>l2){while (l!=0){headA = headA.next;l--;}}else {while (l!=0){headB = headB.next;l--;}}while (headA!=headB){headA = headA.next;headB = headB.next;}return headA;
}
判断回文链表
同LeetCode 234.回文链表
解法一:入栈对比。
ublic boolean isPalindrome(ListNode head) {Stack<ListNode> stack = new Stack<>();ListNode cur = head;int l = 0;// 将全部元素入栈while (cur != null){stack.push(cur);cur = cur.next;l++;}// 比价一半长度即可l /= 2;while (l!=0) {if(head.val != stack.pop().val) return false;head = head.next;l--;}return true;
}
解法二:翻转链表。
使用快慢指针遍历(也可以遍历求长度,然后遍历到链表的中间),然后翻转链表后半部分,再与原链表对比。
public boolean isPalindrome(ListNode head) {ListNode slow = head;ListNode fast = head;while (fast!=null && fast.next!=null){fast = fast.next.next;slow = slow.next;}fast = reverse(slow);while (fast!=null){if(fast.val!= head.val) return false;fast = fast.next;head = head.next;}return true;
}private ListNode reverse(ListNode head) {ListNode cur = head.next;head.next = null;while (cur!=null){ListNode curNext = cur.next;cur.next = head;head = cur;cur = curNext;}return head;
}