两两交换链表中的节点
切入点:要交换那就得找到前一个节点,所以引入dummy node节点。然后就是画图示意一下,如果说偶数个节点,找完之后cur的next是null,如果是奇数个节点,则最后一个节点不需要交换了,就是cur.next.next==null。
然后就是具体的交换逻辑了,注意其中修改指向之后可能造成后续节点找不到,所以得用temp节点提前保存。
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode(-1,head);
ListNode cur = dummy;
ListNode temp,temp1;
while(cur.next!=null && cur.next.next!=null){
temp=cur.next;
temp1=cur.next.next.next;
cur.next=cur.next.next;
cur.next.next=temp;
temp.next=temp1;
cur=temp;
}
return dummy.next;
}
删除链表的倒数第 N 个结点
解法一双指针思想:
首先要弄一个duumy node节点,因为可能删除的是头节点,刚开始两个指针都指向dummy,快指针先走n步,然后快慢指针同时往后走,知道快指针是null,此时慢指针指向了要删除的节点,但是我们要删除结点的话得找到该节点的前一个节点,所以刚开始让快指针指向dummy的next,然后作上述操作,最终慢指针就停在了要删除的节点的上一个节点。
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(-1,head);
ListNode slow=dummy;
ListNode fast=head;
for(int i=0;i<n;i++){
fast=fast.next;
}
while(fast!=null){
slow=slow.next;
fast=fast.next;
}
slow.next=slow.next.next;
return dummy.next;
}
解法二:借助ArrayList
放在arraylist里,删除了倒数第n个节点,然后再建立链表的next指向关系。
public ListNode removeNthFromEnd(ListNode head, int n) {
// 可以用ArrayList来做,先把所有节点放入arrayList,然后删除指定元素,再把arrayList的节点建立链表指向关系,返回头节点
ArrayList<ListNode> arrayList = new ArrayList<>();
ListNode node = head;
while (node != null) {
arrayList.add(node);
node = node.next;
}
// 如果给定链表为空,返回head
if (arrayList.size() == 0) {
return head;
}
// 移除指定元素
arrayList.remove(arrayList.size() - n);
//如果移除后为空,返回null
if (arrayList.size() == 0) {
return null;
}
head = arrayList.get(0);
node = head;
for (int i = 0; i < arrayList.size() - 1; i++) {
node.next = arrayList.get(i + 1);
node = node.next;
}
node.next = null;
return head;
}
面试题 02.07. 链表相交
解法一:双指针 TODO
解法二:借助HashSet
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
HashSet<ListNode> hashset = new HashSet<>();
while(headA!=null){
hashset.add(headA);
headA=headA.next;
}
while(headB!=null){
if(hashset.contains(headB)){
return headB;
}
headB=headB.next;
}
return null;
}
环形链表 II
解法一:快慢指针 TODO
解法二:借助HashSet
用HashSet,遍历链表中的每个节点,记录到HashSet中;一旦遇到了此前遍历过的节点,就存在环,返回该结点。
public ListNode detectCycle(ListNode head) {
HashSet<ListNode> hashset = new HashSet<>();
ListNode node = head;
while(node!=null){
if(hashset.contains(node)){
return node;
}
hashset.add(node);
node = node.next;
}
return null;
}