刷题篇 - 03

题目一:

203. 移除链表元素 - 力扣(LeetCode)

public ListNode removeElements(ListNode head, int val) {
        //1. 如果链表为null,直接返回head
        if (head == null) {
            return head;
        }
        
        //2. 定义快慢指针
        ListNode pre = head;
        ListNode del = pre.next;
        while (pre.next != null) {
            if (del.val == val) {
                pre.next = del.next;
                //del = del.next;
            } else {
                pre = pre.next;
                //del = del.next;
            }
            del = del.next;
        }

        //3. 排查头节点
        if (head.val == val) {
            head = head.next;
        }

        //4. 返回
        return head;
    }

题目二:

206. 反转链表 - 力扣(LeetCode)

public ListNode reverseList(ListNode head) {
        //1. 如果链表为null,直接返回head
        if (head == null) {
            return head;
        }

        //2. 正常
        ListNode cur = head.next;//待交换节点

        //3. 将头节点的next置为null
        head.next = null;

        //4. 进行交换
        while (cur != null) {
            //5. 记录待交换节点的下一个节点
            ListNode curN = cur.next;
            cur.next = head;
            head = cur;
            cur = curN;
        }

        //5. 返回
        return head;
    }

题目三:

876. 链表的中间结点 - 力扣(LeetCode)

public ListNode middleNode(ListNode head) {
        //1. 题目提示:链表一定不为null

        //2. 定义快慢指针
        ListNode fast = head;//每次走两步
        ListNode slow = head;//每次走一步
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }

        //3. 返回
        return slow;
    }

题目四:正

面试题 02.02. 返回倒数第 k 个节点 - 力扣(LeetCode)

public int kthToLast(ListNode head, int k) {
        //新增条件:k不一定合法

        //1. 如果链表为null,k<=0
        if (head == null || k <= 0) {
            return -1;
        }

        //2. 定义快慢指针
        ListNode fast = head;
        ListNode slow = head;

        //3. 快指针先走k-1步,同时判断k的合法性
        for (int i = 0; i < k - 1; i++) {
            //【解析】:当fast.next == null时,fast不能再继续走了
            //if语句写在前面的原因,如果fast.next == null,往后走了之后
            //fast == null,再进入if语句会造成空指针异常
            if (fast.next == null) {
                return -1;
            }
            fast = fast.next;
        }

        //4. 快慢指针同时走
        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }

        //5. 返回
        return slow.val;
    }

题目五:正

21. 合并两个有序链表 - 力扣(LeetCode)

public ListNode mergeTwoLists(ListNode head1, ListNode head2) {
        //1. 定义傀儡节点
        ListNode head = new ListNode(-1);
        ListNode cur = head;

        //2. 开始拼接
        while (head1 != null && head2 != null) {
            if (head1.val < head2.val) {
                cur.next = head1;
                head1 = head1.next;
            } else {
                cur.next = head2;
                head2 = head2.next;
            }
            cur = cur.next;
        }

        //3. 根据出循环的原因分别作出反应(即使两个链表都为空也没关系)
        if (head1 == null) {
            cur.next = head2;
        }

        if (head2 == null) {
            cur.next = head1;
        }

        //3. 返回
        return head.next;
    }

题目六:

链表分割_牛客题霸_牛客网 (nowcoder.com)

public ListNode partition(ListNode pHead, int x) {
        // write code here
        
        //1. 如果链表为null
        if (pHead == null) {
            return pHead;
        }

        //2. 定义两组傀儡节点
        ListNode head1 = new ListNode(-1);
        ListNode cur1 = head1;
        ListNode head2 = new ListNode(-1);
        ListNode cur2 = head2;

        //3. 遍历所给链表
        while (pHead != null) {
            if (pHead.val < x) {
                cur1.next = pHead;
                cur1 = cur1.next;
            } else {
                cur2.next = pHead;
                cur2 = cur2.next;
            }
            pHead = pHead.next;
        }

        //4. 合并两个傀儡链表
        //① 如果前一个链表为null
        if (head1.next == null) {
            return head2.next;
        }
        //② 如果前一个链表不为null(包含后一个链表为null和不为null的情况)
        cur1.next = head2.next;
        cur2.next = null;//最后一个节点的值给了前一个链表,则此时后一个链表的最后一个节点的next一定不是null
        return head1.next;
    }

题目七:正

链表的回文结构_牛客题霸_牛客网 (nowcoder.com)

public boolean chkPalindrome(ListNode A) {
        // write code here

        //1. 如果链表为null
        if (A == null) {
            return true;
        }

        //2. 找到中间节点
        ListNode fast = A;//每次走两步
        ListNode slow = A;//每次走一步
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }

        //3. 翻转中间节点之后的所有节点
        ListNode cur = slow.next;//待翻转节点
        while (cur != null) {
            ListNode curN = cur.next;
            cur.next = slow;
            slow = cur;
            cur = curN;
        }

        //4. 判断是否为回文
        fast = A;
        while (fast != slow) {//链表节点个数为奇数,fast==slow为结束标志
            if (fast.val != slow.val) {//不对称
                return false;
            } else {//对称
                if (fast.next == slow) {//链表节点个数为偶数,fast.next==slow为结束标志
                    return true;//如果是对称的条件,并且满足了偶数节点个数的结束条件,则可直接返回
                }
                fast = fast.next;
                slow = slow.next;
            }
        }

        //5. 返回
        return true;
    }

题目八:正

160. 相交链表 - 力扣(LeetCode)

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        //题目已经提示两个链表的节点个数一定不为0

        //1. 计算两个链表的长度,并假设链表A更长
        int countA = 0;
        int countB = 0;
        ListNode curA = headA;
        ListNode curB = headB;
        while (curA != null) {
            countA++;
            curA = curA.next;
        }
        while (curB != null) {
            countB++;
            curB = curB.next;
        }

        //2. 判断究竟哪个链表更长
        int sub = countA - countB;
        curA = headA;
        curB = headB;
        if (sub < 0) {//此时B链表更长
            curA = headB;
            curB = headA;
            sub = countB - countA;
        }

        //3. 让更长的链表先走sub步
        for (int i = 0; i < sub; i++) {
            curA = curA.next;
        }

        //4. 找相遇节点
        while (curA != null) {//只用判断curA和curB中是否有一个为null即可
            if (curA == curB) {
                return curA;
            }
            curA = curA.next;
            curB = curB.next;
        }

        //5. 代码走到这里一定是因为两个链表不相交
        return null;
    }

题目九:正

141. 环形链表 - 力扣(LeetCode)

public boolean hasCycle(ListNode head) {
        //定义快慢指针(下列代码链表为null也能正确处理)
        ListNode fast = head;//一次走两步
        ListNode slow = head;//一次走一步
        while (fast != null && fast.next != null) {//有顺序要求的原因,如果链表为空,后面的会空指针异常
            fast = fast.next.next;
            slow = slow.next;
            if (fast == slow) {
                return true;
            }
        }
        return false;
    }

题目十:正

142. 环形链表 II - 力扣(LeetCode)

public ListNode detectCycle(ListNode head) {
        //1. 找到快慢指针相遇的节点
        //定义快慢指针(下列代码链表为null也能正确处理)
        ListNode fast = head;//一次走两步
        ListNode slow = head;//一次走一步
        while (fast != null && fast.next != null) {//有顺序要求的原因,如果链表为空,后面的会空指针异常
            fast = fast.next.next;
            slow = slow.next;
            if (fast == slow) {
                break;
            }
        }
        
        //2. 判断是如何出while循环的
        //关于不能以fast != slow作为循环条件的原因
        //答:当链表为null,或链表只有一个节点时,也满足该条件,
        //此时则不能判定是fast==slow的情况
        if (fast == null || fast.next == null) {
            return null;
        }

        //3. 寻找入环点
        fast = head;
        while (fast != slow) {
            fast = fast.next;
            slow = slow.next;
        }

        //4. 返回
        return fast;
    }
  • 13
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值