两个链表的公共子结点
通过建立Hash表辅助查询
先遍历第一个链表head1以val为key,yiNode为value添加到map中
遍历第二个链表head2,遍历并判断map中有无head2,无的话直接下一个,有的话就返回节点
/**
* 方法1:通过Hash辅助查找
*
* @param pHead1
* @param pHead2
* @return
*/
public static ListNode findFirstCommonNodeByMap(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null) {
return null;
}
Map<Integer, ListNode> map = new HashMap<>();
while (pHead1 != null) {
map.put(pHead1.val, pHead1);
pHead1 = pHead1.next;
}
while (pHead2 != null) {
if (!map.containsKey(pHead2.val)) {
pHead2 = pHead2.next;
} else {
return map.get(pHead2.val);
}
}
return null;
}
通过HashSet来辅助查找
/**
* 方法2:通过集合来辅助查找
*
* @param headA
* @param headB
* @return
*/
public static ListNode findFirstCommonNodeBySet(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
Set<ListNode> set = new HashSet<>();
while (headA != null) {
set.add(headA);
headA = headA.next;
}
while (headB != null) {
if (!set.contains(headB)) {
headB = headB.next;
} else {
return headB;
}
}
return null;
}
链表是否为回文序列 LeetCode234
通过双指针进行判断
快慢指针可以找到链表的中间位置,快指针一次走两步,慢指针一次走一步。
但是这里需要注意慢指针到达中点后就无法访问到前边的节点了,所以需要在慢指针前进的过程中做链表反转,才可以做到后续再向前遍历。
/**
* 方法1:通过双指针的方式来判断
*
* @param head
* @return
*/
public static boolean isPalindromeByTwoPoints(ListNode head) {
if (head == null || head.next == null) {
return true;
}
ListNode slow = head;
ListNode fast = head;
ListNode pre = head;
ListNode prePre = null;
while (fast != null && fast.next != null) {
pre = slow;
slow = slow.next;
fast = fast.next.next;
pre.next = prePre;
prePre = pre;
}
while (pre != null && slow != null) {
if (pre.val != slow.val) {
return false;
}
pre = pre.next;
slow = slow.next;
}
return true;
}
通过使用栈
一次遍历将链表的值全部压入栈中,然后遍历链表和栈中的值,出现不一致则表示不是回文。
可以优化为只判断一半的值
/**
* 方法1:通过双指针的方式来判断
*
* @param head
* @return
*/
public static boolean isPalindromeByTwoPoints(ListNode head) {
if (head == null || head.next == null) {
return true;
}
ListNode slow = head;
ListNode fast = head;
ListNode pre = head;
ListNode prePre = null;
while (fast != null && fast.next != null) {
pre = slow;
slow = slow.next;
fast = fast.next.next;
pre.next = prePre;
prePre = pre;
}
while (pre != null && slow != null) {
if (pre.val != slow.val) {
return false;
}
pre = pre.next;
slow = slow.next;
}
return true;
}
合并有序链表
建立新链表 逐个比较两个链表节点的值,取小的插入新链表中。
一个为null之后,直接将剩下不为空的链表整个接上。
/**
* 方法1:建立新链表 逐个比较两个链表节点的值,取小的插入新链表中
*
* @param list1
* @param list2
* @return
*/
public static ListNode mergeTwoLists(ListNode list1, ListNode list2) {
// write code here 建立新链表 逐个比较两个链表节点的值,取小的插入新链表中
ListNode preHead = new ListNode(-1);
ListNode node = preHead;
while (list1 != null && list2 != null) {
if (list1.val > list2.val) {
node.next = list2;
list2 = list2.next;
} else {
node.next = list1;
list1 = list1.next;
}
node = node.next;
}
node.next = list1 == null ? list2 : list1;
return preHead.next;
}