基础数据结构之单向链表练习

1.给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
提示:
链表中节点的数目在范围 [0, 100] 内
0 <= Node.val <= 100
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;
    }
}

public 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;
        }

    public static void main(String[] args) {
        // 创建一个示例链表:1->2->3->4
        ListNode head = new ListNode(1);
        ListNode node2 = new ListNode(2);
        ListNode node3 = new ListNode(3);
        ListNode node4 = new ListNode(4);

        head.next = node2;
        node2.next = node3;
        node3.next = node4;

        Solution solution = new Solution();
        ListNode newHead = solution.swapPairs(head);

        // 打印交换节点后的链表
        ListNode curr = newHead;
        while (curr != null) {
            System.out.print(curr.val + " ");
            curr = curr.next;
        }
    }
}

2.给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你不需要 保留 每个分区中各节点的初始相对位置。

示例 1:

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

输出:[1,2,2,4,3,5]

示例 2:

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

输出:[1,2]

提示: 链表中节点的数目在范围 [0, 200] 内 -100 <= Node.val <= 100 -200 <= x <= 200

public class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }
}
public class Solution {
    public ListNode partition(ListNode head, int x) {
        ListNode smallerHead = new ListNode(0); // 存放小于 x 的节点的链表头节点
        ListNode smallerTail = smallerHead; // 存放小于 x 的节点的链表尾节点
        ListNode greaterEqualHead = new ListNode(0); // 存放大于等于 x 的节点的链表头节点
        ListNode greaterEqualTail = greaterEqualHead; // 存放大于等于 x 的节点的链表尾节点

        while (head != null) {
            if (head.val < x) {
                smallerTail.next = head;
                smallerTail = smallerTail.next;
            } else {
                greaterEqualTail.next = head;
                greaterEqualTail = greaterEqualTail.next;
            }
            head = head.next;
        }
        greaterEqualTail.next = null; // 断开大于等于 x 的节点的链表尾部连接
        smallerTail.next = greaterEqualHead.next; // 将小于 x 的节点链表和大于等于 x 的节点链表连接起
        return smallerHead.next; // 返回小于 x 的节点的链表头节点
    }

    public static void main(String[] args) {
        // 创建一个示例链表:1->4->3->2->5->2
        ListNode head = new ListNode(1);
        ListNode node1 = new ListNode(4);
        ListNode node2 = new ListNode(3);
        ListNode node3 = new ListNode(2);
        ListNode node4 = new ListNode(5);
        ListNode node5 = new ListNode(2);
        head.next = node1;
        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        Solution solution = new Solution();
        int x = 3;
        ListNode newHead = solution.partition(head, x);
        // 打印分隔后的链表
        ListNode curr = newHead;
        while (curr != null) {
            System.out.print(curr.val + " ");
            curr = curr.next;
        }
    }
}
3.     有一个单链表的 head,我们想删除它其中的一个节点 node。
       给你一个需要删除的节点 node 。你将 无法访问 第一个节点  head。
       链表的所有值都是 唯一的,并且保证给定的节点 node 不是链表中的最后一个节点。
       删除给定的节点。注意,删除节点并不是指从内存中删除它。这里的意思是:
       给定节点的值不应该存在于链表中。
       链表中的节点数应该减少 1。
       node 前面的所有值顺序相同。
       node 后面的所有值顺序相同。
       自定义测试:
       对于输入,你应该提供整个链表 head 和要给出的节点 node。node 不应该是链表的最后一个节点,而应该是链表中的一个实际节点。
       我们将构建链表,并将节点传递给你的函数。
       输出将是调用你函数后的整个链表。
       示例 1:
       输入:head = [4,5,1,9], node = 5
       输出:[4,1,9]
       解释:指定链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9
       示例 2:
       输入:head = [4,5,1,9], node = 1
       输出:[4,5,9]
       解释:指定链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9
       提示:
       链表中节点的数目范围是 [2, 1000]
       -1000 <= Node.val <= 1000
       链表中每个节点的值都是唯一的
       需要删除的节点node是链表中的节点 ,且不是末尾节点
public class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }
}
public class Solution {
    public void deleteNode(ListNode node) {
        if (node == null || node.next == null) {
            return; // 无法删除最后一个节点或空节点
        }

        // 将要删除节点的值替换为下一个节点的值
        node.val = node.next.val;
        // 将要删除节点的下一个节点跳过,直接连接到下下个节点
        node.next = node.next.next;
    }

    public static void main(String[] args) {
        // 创建一个示例链表:1->2->3->4->5
        ListNode head = new ListNode(1);
        ListNode node2 = new ListNode(2);
        ListNode node3 = new ListNode(3);
        ListNode node4 = new ListNode(4);
        ListNode node5 = new ListNode(5);

        head.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;

        Solution solution = new Solution();
        ListNode toDelete = node3; // 要删除的节点是3
        solution.deleteNode(toDelete);

        // 打印删除节点后的链表
        ListNode curr = head;
        while (curr != null) {
            System.out.print(curr.val + " ");
            curr = curr.next;
        }
    }
}
4.给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:
输入:head = [1,2]
输出:[2,1]
示例 3:
输入:head = []
输出:[]
提示:
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000
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;
    }
}
public 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;
}
    public static void main(String[] args) {
        // 创建一个示例链表:1->2->3->4
        ListNode head = new ListNode(1);
        ListNode node2 = new ListNode(2);
        ListNode node3 = new ListNode(3);
        ListNode node4 = new ListNode(4);

        head.next = node2;
        node2.next = node3;
        node3.next = node4;

        Solution solution = new Solution();
        ListNode newHead = solution.reverseList(head);

        // 打印交换节点后的链表
        ListNode curr = newHead;
        while (curr != null) {
            System.out.print(curr.val + " ");
            curr = curr.next;
        }
    }
}
5.实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。
注意:本题相对原题稍作改动
示例:
输入: 1->2->3->4->5 和 k = 2
输出: 4
说明:
给定的 k 保证是有效的。
public class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }
}
public class Solution {
    public int kthToLast(ListNode head, int k) {
        if (head == null || k <= 0) {
            return -1; // 返回一个无效值表示未找到符合条件的节点
        }

        ListNode fast = head;
        ListNode slow = head;

        // 将fast指针向前移动k个节点
        for (int i = 0; i < k; i++) {
            if (fast == null) {
                return -1; // k超出链表长度,返回无效值
            }
            fast = fast.next;
        }

        // 同时移动fast和slow指针,直到fast指针到达链表末尾
        while (fast != null) {
            fast = fast.next;
            slow = slow.next;
        }

        return slow.val; // 返回倒数第k个节点的值
    }

    public static void main(String[] args) {
        // 创建一个示例链表:1->2->3->4->5
        ListNode head = new ListNode(1);
        ListNode node2 = new ListNode(2);
        ListNode node3 = new ListNode(3);
        ListNode node4 = new ListNode(4);
        ListNode node5 = new ListNode(5);

        head.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;

        Solution solution = new Solution();
        int kthValue = solution.kthToLast(head, 2);
        System.out.println("倒数第2个节点的值为:" + kthValue);
    }
}

你可能感兴趣的:(基础数据结构,数据结构,算法)