zoukankan      html  css  js  c++  java
  • LeetCode题目练习记录 _数组和链表03 _20211011

    LeetCode题目练习记录 _数组和链表03 _20211011

    206. 反转链表

    难度简单2015收藏分享切换为英文接收动态反馈

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

    示例 1:

    img

    输入:head = [1,2,3,4,5]
    输出:[5,4,3,2,1]
    

    示例 2:

    img

    输入:head = [1,2]
    输出:[2,1]
    

    示例 3:

    输入:head = []
    输出:[]
    

    提示:

    • 链表中节点的数目范围是 [0, 5000]
    • -5000 <= Node.val <= 5000

    进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?

    方法一:迭代

    /**
     * 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; }
     * }
     */
    // Java
    class Solution {
        // 方法一:迭代
        public ListNode reverseList(ListNode head) {
            ListNode prev = null;
            ListNode curr = head;
            for(; curr != null;){
                ListNode next = curr.next;
                curr.next = prev;
                prev = curr;
                curr = next;
            }
            return prev;
        }
    }
    
    /**
     * Definition for singly-linked list.
     * type ListNode struct {
     *     Val int
     *     Next *ListNode
     * }
     */
     // Go 方法一:迭代
    func reverseList(head *ListNode) *ListNode {
        var prev *ListNode
        curr := head
        for curr != nil {
            next := curr.Next // 把下个节点先保存
            curr.Next = prev // 指向一个空节点
            prev = curr // 给这个空节点赋值
            curr = next // 最后实现了翻转 把指向翻了过来 
        }
        return prev
    }
    

    24. 两两交换链表中的节点

    难度中等1069

    给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。

    你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

    示例 1:

    img

    输入:head = [1,2,3,4]
    输出:[2,1,4,3]
    

    示例 2:

    输入:head = []
    输出:[]
    

    示例 3:

    输入:head = [1]
    输出:[1]
    

    提示:

    • 链表中节点的数目在范围 [0, 100]
    • 0 <= Node.val <= 100

    进阶:你能在不修改链表节点值的情况下解决这个问题吗?(也就是说,仅修改节点本身。)

    方法二:递归

    /**
     * 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; }
     * }
     */
    // Java
    class Solution {
        // 方法二:递归
        public ListNode reverseList(ListNode head) {
            if (head == null || head.next == null){
                return head;
            }
            ListNode newHead = reverseList(head.next);
            head.next.next = head;
            head.next = null;
            return newHead;
        }
    }
    
    /**
     * Definition for singly-linked list.
     * type ListNode struct {
     *     Val int
     *     Next *ListNode
     * }
     */
     // Go 方法二:递归
    func reverseList(head *ListNode) *ListNode {
        if head == nil || head.Next == nil {
            return head
        }
        newHead := reverseList(head.Next)
        head.Next.Next = head
        head.Next = nil
        return newHead
    }
    

    24. 两两交换链表中的节点

    难度中等1069

    给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。

    你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

    示例 1:

    img

    输入:head = [1,2,3,4]
    输出:[2,1,4,3]
    

    示例 2:

    输入:head = []
    输出:[]
    

    示例 3:

    输入:head = [1]
    输出:[1]
    

    提示:

    • 链表中节点的数目在范围 [0, 100]
    • 0 <= Node.val <= 100

    进阶:你能在不修改链表节点值的情况下解决这个问题吗?(也就是说,仅修改节点本身。)

    方法一:递归

    /**
     * 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; }
     * }
     */
     // Java
    class Solution {
        // 方法一:递归
        public ListNode swapPairs(ListNode head) {
            if (head == null || head.next == null){
                return head;
            }
            ListNode newHead = head.next;
            head.next = swapPairs(newHead.next);
            newHead.next = head;
            return newHead;
        }
    }
    
    /**
     * Definition for singly-linked list.
     * type ListNode struct {
     *     Val int
     *     Next *ListNode
     * }
     */
     // Go 方法一:递归
    func swapPairs(head *ListNode) *ListNode {
        if head == nil || head.Next == nil {
            return head
        }
        newHead := head.Next
        head.Next = swapPairs(newHead.Next)
        newHead.Next = head
        return newHead
    }
    

    方法二:迭代

    /**
     * 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; }
     * }
     */
    // Java 方法二:迭代
    class Solution {
        public ListNode swapPairs(ListNode head) {
            ListNode dummyHead = new ListNode(0);
            dummyHead.next = head;
            ListNode temp = dummyHead;
            while(temp.next != null && temp.next.next != null){
                ListNode node1 = temp.next;
                ListNode node2 = temp.next.next;
                temp.next = node2;
                node1.next = node2.next;
                node2.next = node1;
                temp = node1;
            }
            return dummyHead.next;
        }
    }
    
    /**
     * Definition for singly-linked list.
     * type ListNode struct {
     *     Val int
     *     Next *ListNode
     * }
     */
     // Go 方法二:迭代
    func swapPairs(head *ListNode) *ListNode {
        dummyHead := &ListNode{0,head}
        temp := dummyHead
        for temp.Next != nil && temp.Next.Next != nil {
            node1 := temp.Next
            node2 := temp.Next.Next
            temp.Next = node2
            node1.Next = node2.Next
            node2.Next = node1
            temp = node1
        }
        return dummyHead.Next
    }
    

    141. 环形链表

    难度简单1223

    给定一个链表,判断链表中是否有环。

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

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

    进阶:

    你能用 O(1)(即,常量)内存解决此问题吗?

    示例 1:

    img

    输入:head = [3,2,0,-4], pos = 1
    输出:true
    解释:链表中有一个环,其尾部连接到第二个节点。
    

    示例 2:

    img

    输入:head = [1,2], pos = 0
    输出:true
    解释:链表中有一个环,其尾部连接到第一个节点。
    

    示例 3:

    img

    输入:head = [1], pos = -1
    输出:false
    解释:链表中没有环。
    

    提示:

    • 链表中节点的数目范围是 [0, 104]
    • -105 <= Node.val <= 105
    • pos-1 或者链表中的一个 有效索引

    方法一:哈希表

    /**
     * Definition for singly-linked list.
     * class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
     // Java 方法一:哈希表
    public class Solution {
        public boolean hasCycle(ListNode head) {
            Set<ListNode> seen = new HashSet<ListNode>();
            while(head != null) {
                if(!seen.add(head)) {
                    return true;
                }
                head = head.next;
            }
            return false;
        }
    }
    
    /**
     * Definition for singly-linked list.
     * type ListNode struct {
     *     Val int
     *     Next *ListNode
     * }
     */
     // Go 方法一:哈希表
    func hasCycle(head *ListNode) bool {
        seen := map[*ListNode]struct{}{}
        for head != nil {
            if _,ok := seen[head]; ok {
                return true
            }
            seen[head] = struct{}{}
            head = head.Next
        }
        return false
    }
    

    方法二:快慢指针

    /**
     * Definition for singly-linked list.
     * class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
     // Java 方法二:快慢指针
    public class Solution {
        public boolean hasCycle(ListNode head) {
            if (head == null || head.next == null) {
                return false;
            }
            ListNode slow = head;
            ListNode fast = head.next;
            while(slow != fast){
                if (fast == null || fast.next == null) {
                    return false;
                }
                slow = slow.next;
                fast = fast.next.next;
            }
            return true;
        }
    }
    
    /**
     * Definition for singly-linked list.
     * type ListNode struct {
     *     Val int
     *     Next *ListNode
     * }
     */
     // Go 方法二:快慢指针
    func hasCycle(head *ListNode) bool {
        if head == nil || head.Next == nil {
            return false
        }
        slow, fast := head, head.Next
        for fast != slow {
            if fast == nil || fast.Next == nil {
                return false
            }
            slow = slow.Next
            fast = fast.Next.Next
        }
        return true
    }
    

    142. 环形链表 II

    难度中等1215

    给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

    为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos-1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

    说明:不允许修改给定的链表。

    进阶:

    • 你是否可以使用 O(1) 空间解决此题?

    示例 1:

    img

    输入:head = [3,2,0,-4], pos = 1
    输出:返回索引为 1 的链表节点
    解释:链表中有一个环,其尾部连接到第二个节点。
    

    示例 2:

    img

    输入:head = [1,2], pos = 0
    输出:返回索引为 0 的链表节点
    解释:链表中有一个环,其尾部连接到第一个节点。
    

    示例 3:

    img

    输入:head = [1], pos = -1
    输出:返回 null
    解释:链表中没有环。
    

    提示:

    • 链表中节点的数目范围在范围 [0, 104]
    • -105 <= Node.val <= 105
    • pos 的值为 -1 或者链表中的一个有效索引

    方法一:哈希表

    /**
     * Definition for singly-linked list.
     * class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
     // Java 方法一:哈希表
    public class Solution {
        public ListNode detectCycle(ListNode head) {
            ListNode pos = head;
            Set<ListNode> visited = new HashSet<ListNode>();
            while(pos != null){
                if (visited.contains(pos)) {
                    return pos;
                }else {
                    visited.add(pos);
                }
                pos = pos.next;
            }
            return null;
        }
    }
    
    /**
     * Definition for singly-linked list.
     * type ListNode struct {
     *     Val int
     *     Next *ListNode
     * }
     */
     // Go 方法一:哈希表
    func detectCycle(head *ListNode) *ListNode {
        seen := map[*ListNode]struct{}{}
        for head != nil {
            if _, ok := seen[head]; ok {
                return head
            }
            seen[head] = struct{}{}
            head = head.Next
        }
        return nil
    }
    

    方法二:快慢指针

    /**
     * Definition for singly-linked list.
     * class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) {
     *         val = x;
     *         next = null;
     *     }
     * }
     */
    // Java 方法二:快慢指针
    public class Solution {
        public ListNode detectCycle(ListNode head) {
            if (head == null){
                return null;
            }
            ListNode slow = head;
            ListNode fast = head;
            while (fast != null) {
                slow = slow.next;
                if (fast.next != null) {
                    fast = fast.next.next;
                }else {
                    return null;
                }
                if(fast == slow) {
                    ListNode ptr = head;
                    while (ptr != slow) {
                        ptr = ptr.next;
                        slow = slow.next;
                    }
                    return ptr;
                }
            }
            return null;
        }
    }
    
    /**
     * Definition for singly-linked list.
     * type ListNode struct {
     *     Val int
     *     Next *ListNode
     * }
     */
     // Go 方法二:快慢指针
    func detectCycle(head *ListNode) *ListNode {
        slow, fast := head, head
        for fast != nil{
            slow = slow.Next
            if fast.Next == nil {
            return nil
            }
            fast = fast.Next.Next
            if fast == slow {
                p := head
                for p != slow {
                    p = p.Next
                    slow = slow.Next
                }
                return p
            }
        }
        return nil
    }
    

    25. K 个一组翻转链表

    难度困难1314

    给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

    k 是一个正整数,它的值小于或等于链表的长度。

    如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

    进阶:

    • 你可以设计一个只使用常数额外空间的算法来解决此问题吗?
    • 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

    示例 1:

    img

    输入:head = [1,2,3,4,5], k = 2
    输出:[2,1,4,3,5]
    

    示例 2:

    img

    输入:head = [1,2,3,4,5], k = 3
    输出:[3,2,1,4,5]
    

    示例 3:

    输入:head = [1,2,3,4,5], k = 1
    输出:[1,2,3,4,5]
    

    示例 4:

    输入:head = [1], k = 1
    输出:[1]
    

    提示:

    • 列表中节点的数量在范围 sz
    • 1 <= sz <= 5000
    • 0 <= Node.val <= 1000
    • 1 <= k <= sz

    方法一:模拟

    /**
     * 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; }
     * }
     */
     // Java 方法一:模拟
    class Solution {
        public ListNode reverseKGroup(ListNode head, int k) {
            ListNode hair = new ListNode(0);
            hair.next = head;
            ListNode pre = hair;
    
            while (head != null) {
                ListNode tail = pre;
                // 检查剩余的长度是否大于等于k
                for (int i=0; i < k; i++) {
                    tail = tail.next;
                    if (tail == null) {
                        return hair.next;
                    }
                }
                ListNode nex = tail.next;
                ListNode[] reverse = myReverse(head, tail);
                head = reverse[0];
                tail = reverse[1];
                // 把子链表重新接回原链表
                pre.next = head;
                tail.next = nex;
                pre = tail;
                head = tail.next;
            } 
            return hair.next;
        }
    
        public ListNode[] myReverse(ListNode head,ListNode tail) {
            ListNode prev = tail.next;
            ListNode p = head;
            while (prev != tail) {
                ListNode nex = p.next;
                p.next = prev;
                prev = p;
                p = nex;
            }
            return new ListNode[]{tail,head};
        }
    }
    
    /**
     * Definition for singly-linked list.
     * type ListNode struct {
     *     Val int
     *     Next *ListNode
     * }
     */
      // Go 方法一:模拟
    func reverseKGroup(head *ListNode, k int) *ListNode {
        hair := &ListNode{Next: head}
        pre := hair
    
        for head != nil {
            tail := pre
            for i := 0; i < k; i++ {
                tail = tail.Next
                if tail == nil {
                    return hair.Next
                }
            }
            nex := tail.Next
            head, tail = myReverse(head, tail)
            pre.Next = head
            tail.Next = nex
            pre = tail
            head = tail.Next
        }
        return hair.Next
    }
    
    func myReverse(head, tail *ListNode) (*ListNode, *ListNode) {
        prev := tail.Next
        p := head
        for prev != tail {
            nex := p.Next
            p.Next = prev
            prev = p
            p = nex
        }
        return tail, head
    }
    
  • 相关阅读:
    [ 黑盒测试方法 ] 错误猜测法
    [ 黑盒测试方法 ] 边界值分析法
    [ 黑盒测试方法 ] 等价类划分法
    [ Python入门教程 ] Python面向对象编程(下)
    [ Python入门教程 ] Python面向对象编程(上)
    [ Python入门教程 ] Python模块定义和使用
    [ Python入门教程 ] Python常用内置函数介绍
    [ Python入门教程 ] Python函数定义和使用
    MyBatis的缓存分析
    微机原理与接口技术总计
  • 原文地址:https://www.cnblogs.com/OwlInTheOaktree/p/15393425.html
Copyright © 2011-2022 走看看