day15-链表-141/21/203/83/206

121 阅读3分钟

第一题

题目

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false

image.png

思路

使用set集合进行判断,只要加next指向一样的话,就不能再add,说明有环

代码

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        Set<ListNode> set = new HashSet<ListNode>();
        boolean res = false;
        while(head != null) {
            if(!set.add(head)) {
                res = true;
                break;
            };
            head = head.next;
        };
        return res;
    }
}

第二题

题目

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

image.png

思路

1、递归-一看就懂,一写就不会

2、遍历-只要是遍历,一定要新定义一个节点,来进行while的判断,否则的话会改变最终结果的头节点(或者结果.next)的指向,一定要有一个中介

代码

1、递归

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        if(list1 == null) {
            return list2;
        }
        if(list2 == null) {
            return list1;
        }
        if(list1.val <= list2.val) {
            list1.next = mergeTwoLists(list1.next, list2);
            return list1;
        }else {
            list2.next = mergeTwoLists(list1, list2.next);
            return list2;
        }
    }
}

2、遍历

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode res = new ListNode();
        ListNode testRes = res;
        while(list1 != null && list2 != null) {
            if(list1.val > list2.val) {
                testRes.next = list2;
                list2 = list2.next;
            }else{
                testRes.next = list1;
                list1 = list1.next;
            };
            testRes = testRes.next;
        };
        testRes.next = list1 == null ? list2 : list1;
        return res.next;
    }
}

第三题

题目

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点

思路

1、遍历-定义一个新的节点,指向head,判断新的节点的next是否存在,存在,进行val的判断

2、递归

代码

1、遍历

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode res = new ListNode();
        res.next = head;
        ListNode resCopy = res;
        while(resCopy.next != null) {
            if(resCopy.next.val == val) {
                resCopy.next = resCopy.next.next;
            }else {
                resCopy = resCopy.next;
            };
        };
        return res.next;
    }
}

2、递归

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        if(head == null) return head;
        if(head.val == val) {
            head = removeElements(head.next, val);
        }else {
            head.next = removeElements(head.next, val);
        };
        return head;
    }
}

第四题

题目

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表

image.png

思路

1、遍历

代码

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        ListNode resCopy = head;
        while(resCopy != null && resCopy.next != null) {
            if(resCopy.val == resCopy.next.val) {
                resCopy.next = resCopy.next.next;
            }else {
                resCopy = resCopy.next;
            };
        };
        return head;
    }
}

第五题

题目

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表

image.png

思路

1、递归

2、遍历-按照之前的方法遍历

3、遍历-直接使用构造函数

代码

1、递归

class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null || head.next == null) {
            return head;
        }
        ListNode res = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return res;
    }
}

2、遍历

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        while (curr != null) {
            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }
}

2、构造函数

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode res = null;
        for(ListNode i = head; i!=null; i=i.next) {
            res = new ListNode(i.val, res);
        }
        return res;
    }
}