链表总结(2)

2023-12-30 10:32:02

theme: fancy

又是链表专题啦,老样子,标题就是leetcode链接,在这里只放我的代码答案和注释

141环形链表

public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head == null || head.next == null)   return false;
        if(head.next == head) return true;
        ListNode slow = head;
        ListNode fast = head.next;
        while(slow != fast) {
            slow = slow.next;
            fast = fast.next;
            if(fast == null)    break; 
            fast = fast.next;
            if(fast == null)    break;  // 告诉我们每一步走的路都要检查一下
            if(slow == fast && fast != null) {
                return true;
            }
        }
        return false;
    }
}

142环形链表2

public class Solution {
    public ListNode detectCycle(ListNode head) {
        if(head == null || head.next == null)   return null;
        ListNode slow = head;
        ListNode fast = head.next;
        while(fast != null) {   // 这个判断条件很关键
            slow = slow.next;
            fast = fast.next;
            if(fast == null)    break; 
            fast = fast.next;
            if(slow == fast) {
                slow = head;
                fast = fast.next;
                while(slow != fast) {  // 开始循环找到相遇的起始点
                    slow = slow.next;
                    fast = fast.next;
                }
                if(slow == fast) {
                    return fast;
                }
            }
        }
        return null;
    }
}

21合并两个有序链表

class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        // 创建两个指针 cur 和 ans,ans 用于记录合并后链表的头部,cur 用于迭代操作
        ListNode cur = new ListNode(), ans = cur;

        // 循环直到 list1 和 list2 都遍历完
        while(list1 != null && list2 != null) {
            // 比较 list1 和 list2 当前节点的值,将较小值的节点接入合并后的链表
            if(list1.val > list2.val) {
                ans.next = list2;
                list2 = list2.next;
            } else {
                ans.next = list1;
                list1 = list1.next;
            }
            ans = ans.next; // 移动合并后链表的指针到下一个节点
        }

        // 处理某个链表遍历完后,将剩余未遍历完的链表直接接入合并后的链表末尾
        ans.next = list1 == null ? list2 : list1;

        return cur.next; // 返回合并后链表的头节点
    }
}

2两数相加

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
/ 创建一个ArrayList来存储相加的结果  
        List<Integer> ans = new ArrayList<>();  
          
        // 当l1和l2都不为空时,进行相加操作  
        while(l1 != null && l2 != null) {  
            int a = l1.val;  // 获取l1的当前值  
            int b = l2.val;   // 获取l2的当前值  
            ans.add(a + b);    // 将a和b相加的结果添加到ans中  
            l1 = l1.next;       // 将l1移动到下一个节点  
            l2 = l2.next;        // 将l2移动到下一个节点  
        }  
          
        // 如果l1或l2有一个为空,另一个不为空,将非空链表的剩余部分添加到ans中  
        if(l1 != null || l2 != null) {  
            ListNode cur = (l1 == null ? l2 : l1);  // 确定非空链表的起始节点  
            while(cur != null) {  
                ans.add(cur.val);  // 将非空链表的剩余部分添加到ans中  
                cur = cur.next;    // 将cur移动到下一个节点  
            }  
        }  
          
        // 初始化结果链表的头节点res和尾节点res2  
        ListNode res = new ListNode();  
        ListNode res2 = res;  // res2用于返回结果链表的头节点,因为res可能被重新赋值  
          
        // 初始化进位标志go,初始值为0  
        int go = 0;  
        for(int i = 0; i < ans.size(); i ++) {  // 遍历ans中的每个数字  
            System.out.println(ans.get(i));  // 打印当前数字,用于调试或测试目的  
            int temp = go;  // 存储当前的进位值  
            go = 0;  // 重置进位值为0,因为当前数字已经处理完毕  
            if(ans.get(i) + temp > 9) {  // 如果当前数字加上之前的进位值大于9,需要进行进位处理  
                go ++;  // 进位值为1,因为需要向高位进位  
                temp += ans.get(i) - 10;  // 减去10是为了在下一次循环中处理进位后的数字部分  
            } else {  // 如果当前数字加上之前的进位值小于等于9,不需要进行进位处理  
                temp += ans.get(i);  // 将当前数字加到temp上,作为下一次循环处理的新数字的一部分  
            }  
            res.next = new ListNode(temp);  // 将temp作为新的节点添加到结果链表中  
            res = res.next;  // 将res移动到新添加的节点上,以便在下一次循环中处理下一个数字部分  
        }  
        if(go != 0) {  // 如果最终仍有进位,则添加一个值为1的节点到结果链表的末尾(作为进位表示)  
            res.next = new ListNode(1);  // 将进位值1作为新的节点添加到结果链表的末尾(如果存在)  
        } else {  // 如果最终没有进位,则返回结果链表的头节点(即res2)作为最终结果链表的起始节点  
            return res2.next;  // 返回结果链表的头节点(即res2的下一个节点)作为最终结果链表的起始节点  
        }  
    }  

这里的注释是让文心一言帮我加的,老实说加的太多了太详细了。。。

19删除链表的倒数第 N 个结点

image.png

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        if(head == null)    return head;
        ListNode cur = head;
        int size = 0;
        while(cur != null) {
            size ++;
            cur = cur.next;
        }
        if(n == size) return head.next;  // 这个是专门为了过特殊用例写的
        cur = new ListNode(-1, head);
        for(int i = 0;i < size - n;i ++) {
            cur = cur.next;
        }
        cur.next = cur.next.next;
        return head;
    }
}

文章来源:https://blog.csdn.net/m0_51547272/article/details/135290074
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。