代码随想录刷题Day5

58 阅读3分钟

链表

  1. 206. 反转链表
  • 方法一:双指针法/迭代

image.png

image.png

首先定义一个cur保存head,再定义一个pre初始化为null。

然后就要开始食物了,首先决定 用 tmp 指针保存cur->next 节点(图里的2),接下来要改变 cur->next 的指向了,将 cur->next 指向 pre

接下来,就是循环走下面的代码逻辑了,继续移动pre和cur指针。

最后,cur指针已经指向了空,循环结束,链表也完成了。这时我们返回pre指针就可以了,pre指针就指向了新的头结点。

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode pre=null;
        ListNode cur=head;
        while(cur!=null){
            ListNode tmp=cur.next;
            cur.next=pre;
            pre=cur;
            cur=tmp;
        }
        return pre;
    }
}
  • 方法2:递归
class Solution {
    public ListNode reverseList(ListNode head) {
        return reverse(head,null);
    }
    public ListNode reverse(ListNode cur,ListNode pre){
        if(cur==null){//终止条件
            return pre;
        }
        ListNode tmp = cur.next;
        cur.next=pre;
        return reverse(tmp,cur);
    }
}
  1. 24. 两两交换链表中的节点
  • 迭代

image.png

image.png

class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode();//创建虚拟头结点
        dummy.next=head;//定义头指针
        ListNode tmp=dummy;// 定义一个临时结点
        while(tmp.next!=null&&tmp.next.next!=null){
            ListNode node1=tmp.next;//看第一张图
            ListNode node2=tmp.next.next;//看第一张图
            tmp.next=node2;//第二张图,tmp指向node2
            node1.next=node2.next;//node1指向数字3的位置
            node2.next=node1;//node2指向node1,此时数字1和2已经交换
            tmp=node1;//tmp指向交换后的node1(现在在数字2的位置),继续下一个循环
        }
        return dummy.next;
    }
}
  1. 19. 删除链表的倒数第 N 个结点
  • 方法一:计算链表长度
  • 我的思路:1、创建虚拟头结点 2、计算链表长度index 3、删除下标为index-n的结点
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode();//创建虚拟头结点
        dummy.next=head;//定义头指针
        ListNode pre=dummy;// 定义一个临时结点
        int index=0;
        while(head!=null){
            index++;
            head=head.next;
        }
        for(int i=0;i<index-n;i++){
            pre=pre.next;
        }
        pre.next=pre.next.next;
        return dummy.next;
    }
}
  • 方法2:双指针
  • 如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。妙!

image.png

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);//创建虚拟头结点
        dummy.next=head;//定义头指针
        ListNode fast=dummy;// 定义快指针
        ListNode slow=dummy;// 定义慢指针
        for(int i=0;i<n+1;i++){//n+1是因为只有这样同时移动的时候slow才能指向删除节点的上一个节点,这个要想一下不然容易错
            fast=fast.next;
        }
        while(fast!=null){//看图
            fast=fast.next;
            slow=slow.next;
        }
        slow.next=slow.next.next;
        return dummy.next;
    }
}
  1. 面试题 02.07. 链表相交
  • 个人思路
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int m=length(headA);//定义链表A长度
        int n=length(headB);//定义链表B长度
        int k=Math.abs(m-n);//链表A与B长度差
        ListNode curA=headA;//curA指向链表A的头结点
        ListNode curB=headB;//curB指向链表B的头结点
        while(k>0){//让curA和curB对齐
           if(m<n) curB=curB.next;
           else{curA=curA.next;}
           k--;
       }
        while(curA!=null&&curB!=null){
            if(curA==curB){//此题关键!交点不是数值相等,而是指针相等!
                return curA;
            }
            curA=curA.next;//不同,同时向后移动curA和curB
            curB=curB.next;
        }
        return null;
    }
    public int length(ListNode head){//计算链表长度
        int length=0;
        while(head!=null){
            length++;
            head=head.next;
        }
        return length;
    }
}
  • 双指针
  • leetcode.cn/problems/in…
  • 思路是指针A遍历完headA再遍历headB,指针B遍历完headB再遍历headA,如果他们有交点就返回首个公共结点,没有交点最后就返回null image.png

image.png

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode A = headA, B = headB;
        while (A != B) {
            if(A==null){
                A=headB;
            }else{
                A=A.next;
            }
            if(B==null){
                B=headA;
            }else{
                B=B.next;
            }

            // A = A != null ? A.next : headB;
            // B = B != null ? B.next : headA;
        }
        return A;
    }
}