Java每日一练(20230502) BST公共祖先、随机分组、K个一组翻转链表

简介: Java每日一练(20230502) BST公共祖先、随机分组、K个一组翻转链表

1. 二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5]

示例 1:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8

输出: 6

解释: 节点 2 和节点 8 的最近公共祖先是 6。



示例 2:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4

输出: 2

解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。


说明:

  • 所有节点的值都是唯一的。
  • p、q 为不同节点且均存在于给定的二叉搜索树中。

出处:

https://edu.csdn.net/practice/26945721

代码:

import java.util.*;
import java.util.LinkedList;
public class lowestCommonAncestor {
    public final static int NULL = Integer.MIN_VALUE; //用NULL来表示空节点
    public static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x) {
            val = x;
        }
    }
    public static class Solution {
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            if (p.val < root.val && q.val < root.val)
                return lowestCommonAncestor(root.left, p, q);
            else if (p.val > root.val && q.val > root.val)
                return lowestCommonAncestor(root.right, p, q);
            else
                return root;
        }
    }
    public static TreeNode createBinaryTree(Vector<Integer> vec) {
        if (vec == null || vec.size() == 0) {
            return null;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        TreeNode root = new TreeNode(vec.get(0));
        queue.offer(root);
        int i = 1;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int j = 0; j < size; j++) {
                TreeNode node = queue.poll();
                if (i < vec.size() && vec.get(i) != NULL) {
                    node.left = new TreeNode(vec.get(i));
                    queue.offer(node.left);
                }
                i++;
                if (i < vec.size() && vec.get(i) != NULL) {
                    node.right = new TreeNode(vec.get(i));
                    queue.offer(node.right);
                }
                i++;
            }
        }
        return root;
    }
    public static void main(String[] args) {
        Solution s = new Solution();
        Integer[] nums = {6,2,8,0,4,7,9,NULL,NULL,3,5};
        Vector<Integer> vec = new Vector<Integer>(Arrays.asList(nums));
        TreeNode root = createBinaryTree(vec);
        TreeNode p = new TreeNode(2);
        TreeNode q = new TreeNode(8);
        System.out.println(s.lowestCommonAncestor(root, p, q).val);
        Integer[] nums2 = {6,2,8,0,4,7,9,NULL,NULL,3,5};
        vec = new Vector<Integer>(Arrays.asList(nums2));
        root = createBinaryTree(vec);
        p = new TreeNode(2);
        q = new TreeNode(4);
        System.out.println(s.lowestCommonAncestor(root, p, q).val);
    }
}

输出:

6

2


2. 随机分组问题

已知有16只男子足球队参加2008年奥运会。写一段程序将球队随机分成4组

出处:

https://edu.csdn.net/practice/26945722

代码:

import java.util.*;
class StringToDateDemo {
    public static void main(String args[]) {
        ArrayList<String> teams = new ArrayList<String>() {
            {
                add("a");
                add("b");
                add("c");
                add("d");
                add("e");
                add("f");
                add("g");
                add("h");
                add("i");
                add("j");
                add("k");
                add("l");
                add("m");
                add("n");
                add("o");
                add("p");
            }
        };
        Collections.shuffle(teams);
        ArrayList<String> group1 = new ArrayList<String>();
        ArrayList<String> group2 = new ArrayList<String>();
        ArrayList<String> group3 = new ArrayList<String>();
        ArrayList<String> group4 = new ArrayList<String>();
        group1.addAll(teams.subList(0, teams.size() / 4 + teams.size() % 4));
        group2.addAll(teams.subList(teams.size() / 4 + teams.size() % 4, 2 * teams.size() / 4 + teams.size() % 4));
        group3.addAll(teams.subList(2*teams.size() / 4 + teams.size() % 4, 3 * teams.size() / 4 + teams.size() % 4));
        group4.addAll(teams.subList(3*teams.size() / 4 + teams.size() % 4, teams.size()));
    }
}

输出:(随机)

[h, a, i, n]

[j, l, k, e]

[b, p, g, c]

[o, d, f, m]

Tips: 因为是连续字母,ArrayList teams 用循环赋值即可。

ArrayList teams = new ArrayList<>();
for (int i = 0; i < 16; i++) {
    teams.add(String.valueOf((char)(i + 'a')));
}

3. K 个一组翻转链表

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

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

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

进阶:

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

示例 1:

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

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


示例 2:

输入: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

以下程序实现了这一功能,请你填补空白处内容:

```Java
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 reverseKGroup(ListNode head, int k) {
        if (head == null) {
            return null;
        }
        ListNode a = head, b = head;
        for (int i = 0; i < k; i++) {
            if (b == null) {
                return a;
            }
            b = b.next;
        }
        ListNode newHead = reverse(a, b);
        a.next = reverseKGroup(b, k);
        return newHead;
    }
    public ListNode reverse(ListNode a, ListNode b) {
        ListNode pre, cur, nxt;
        pre = null;
        cur = a;
        nxt = a;
        while (nxt != b) {
            __________________;
        }
        return pre;
    }
}
```

出处:

https://edu.csdn.net/practice/26945723

代码:

import java.util.*;
import java.util.LinkedList;
public class reverseKGroup {
    public static 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 static class Solution {
        public ListNode reverseKGroup(ListNode head, int k) {
            if (head == null) {
                return null;
            }
            ListNode a = head, b = head;
            for (int i = 0; i < k; i++) {
                if (b == null) {
                    return a;
                }
                b = b.next;
            }
            ListNode newHead = reverse(a, b);
            a.next = reverseKGroup(b, k);
            return newHead;
        }
        public ListNode reverse(ListNode a, ListNode b) {
            ListNode pre, cur, nxt;
            pre = null;
            cur = a;
            nxt = a;
            while (nxt != b) {
                nxt = cur.next;
                cur.next = pre;
                pre = cur;
                cur = nxt;
            }
            return pre;
        }
    }
    public static ListNode createLinkedList(int[] nums) {
        if (nums == null || nums.length == 0) {
            return null;
        }
        ListNode head = new ListNode(nums[0]);
        ListNode cur = head;
        for (int i = 1; i < nums.length; i++) {
            cur.next = new ListNode(nums[i]);
            cur = cur.next;
        }
        return head;
    }
    public static void printLinkedList(ListNode head) {
        ListNode cur = head;
        while (cur != null) {
            System.out.print(cur.val + "->");
            cur = cur.next;
        }
        System.out.println("null");
    }
    public static void main(String[] args) {
        Solution s = new Solution();
        int[] nums = {1,2,3,4,5};
        ListNode head = createLinkedList(nums);
        printLinkedList(head);
        printLinkedList(s.reverseKGroup(head, 2));
        head = createLinkedList(nums);
        printLinkedList(s.reverseKGroup(head, 3));
        head = createLinkedList(nums);
        printLinkedList(s.reverseKGroup(head, 1));
    }
}

输出:

1->2->3->4->5->null

2->1->4->3->5->null

3->2->1->4->5->null

1->2->3->4->5->null


🌟 每日一练刷题专栏 🌟

持续,努力奋斗做强刷题搬运工!

👍 点赞,你的认可是我坚持的动力!

🌟 收藏,你的青睐是我努力的方向!

评论,你的意见是我进步的财富!  

主页:https://hannyang.blog.csdn.net/


目录
相关文章
|
3月前
|
Python
【Leetcode刷题Python】25.K 个一组翻转链表
解决LeetCode "K 个一组翻转链表" 问题的三种方法:使用栈、尾插法和虚拟节点顺序法,并提供了每种方法的Python实现代码。
31 0
|
2月前
|
Java
java数据结构,双向链表的实现
文章介绍了双向链表的实现,包括数据结构定义、插入和删除操作的代码实现,以及双向链表的其他操作方法,并提供了完整的Java代码实现。
java数据结构,双向链表的实现
|
1月前
|
存储 安全 Java
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
23 3
|
2月前
|
Java Go PHP
Java分组匹配
Java分组匹配
26 5
|
3月前
|
存储 Java
|
3月前
|
算法 Java
【Java集合类面试十八】、ConcurrentHashMap是怎么分段分组的?
ConcurrentHashMap通过分段锁(Segment)实现高效并发访问,get操作无需加锁,而put操作首先判断是否需要扩容,然后通过两次hash定位并尝试使用CAS和锁机制安全地添加元素。
|
3月前
|
存储 Java
java实现单链表的创建、增、删、改、查
这篇文章详细介绍了Java中如何实现单链表的创建以及对单链表进行增加、删除、修改、查询等操作的方法,并提供了相应的代码示例。
java实现单链表的创建、增、删、改、查
|
3月前
|
传感器 定位技术 C++
基于C++的GDAL用空白栅格填充长时间序列遥感影像中的缺失图像
然后,定义需要处理的遥感影像路径列表,和识别数据缺失的逻辑。这里我们简化处理,假设已经知道哪一幅图像是缺失的,因此直接跳过识别步骤。
56 1
|
3月前
|
存储 Java
【Java集合类面试十】、HashMap中的循环链表是如何产生的?
在多线程环境下,HashMap在扩容时如果发生条件竞争,元素的插入顺序可能形成循环链表,导致死循环。
|
3月前
|
存储 Java
java实现双向链表的增删改查
这篇文章展示了如何在Java中实现双向链表的增加、删除、修改和查询操作,并通过代码示例演示了在双向链表中存储和操作学生信息的过程。