Java每日一练(20230403) 字母异位词分组、删除链表的倒数第 N 个结点、合并区间

简介: Java每日一练(20230403) 字母异位词分组、删除链表的倒数第 N 个结点、合并区间

1. 字母异位词分组

给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

示例:

输入:[eat", "tea", "tan", "ate", "nat", "bat"]

输出:[[ate","eat","tea"],["nat","tan"],["bat"]]

说明:

  • 所有输入均为小写字母。
  • 不考虑答案输出的顺序。

出处:

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

代码:

方法一:对每个字符串排序后作为key,将同一key的字符串放入同一个ArrayList中,最后返回所有ArrayList。

方法二:使用计数器的方式,统计每个字符出现的次数,将计数器中的数字拼接成一个字符串作为key,将同一key的字符串放入同一个ArrayList中,最后返回所有ArrayList。

import java.util.*;
public class groupAnagrams {
    public static List<List<String>> groupAnagrams(String[] strs) {
        HashMap<String, ArrayList<String>> map = new HashMap<>();
        for (String str : strs) {
            char[] cs = str.toCharArray();
            Arrays.sort(cs);
            String key = String.valueOf(cs);
            if (!map.containsKey(key)) {
                map.put(key, new ArrayList<>());
            }
            map.get(key).add(str);
        }
        return new ArrayList<>(map.values());
    }
    public static List<List<String>> groupAnagrams2(String[] strs) {
        if (strs.length <= 0) {
            return new ArrayList<>();
        }
        HashMap<String, ArrayList<String>> map = new HashMap<>();
        for (String str : strs) {
            char[] cs = str.toCharArray();
            int[] count = new int[26];
            for (char c : cs) {
                ++count[c - 'a'];
            }
            StringBuilder s = new StringBuilder("");
            for (int num : count) {
                s.append(num);
            }
            String key = String.valueOf(s);
            if (!map.containsKey(key)) {
                map.put(key, new ArrayList<>());
            }
            map.get(key).add(str);
        }
        return new ArrayList<>(map.values());
    }
    public static void main(String[] args) {
        String[] words = {"eat", "tea", "tan", "ate", "nat", "bat"};
        for (List<String> word : groupAnagrams(words)) {
            System.out.print(word);
            System.out.print("");
        }
        System.out.println();
        for (List<String> word : groupAnagrams2(words)) {
            System.out.print(word);
            System.out.print("");
        }
        System.out.println();
    }
}

输出:

[eat, tea, ate][bat][tan, nat]

[bat][tan, nat][eat, tea, ate]


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

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

进阶:你能尝试使用一趟扫描实现吗?

示例 1:

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

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


示例 2:

输入:head = [1], n = 1

输出:[]

示例 3:

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

输出:[1]


提示:

  • 链表中结点的数目为 sz
  • 1 <= sz <= 30
  • 0 <= Node.val <= 100
  • 1 <= n <= sz

出处:

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

代码:

import java.util.*;
public class removeNthFromEnd {
    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 removeNthFromEnd(ListNode head, int n) {
            ListNode v = new ListNode(0, head);
            ListNode handle = v;
            List<ListNode> index = new ArrayList<>();
            while (v != null) {
                index.add(v);
                v = v.next;
            }
            int pre = index.size() - n - 1;
            int next = index.size() - n + 1;
            index.get(pre).next = next >= 0 && next < index.size() ? index.get(next) : null;
            return handle.next;
        }
    }
    public static ListNode[] arraysToLists(int[][] nums) {
        ListNode[] lists = new ListNode[nums.length];
        for (int i = 0; i < nums.length; i++) {
            int[] arr = nums[i];
            ListNode head = new ListNode(0);
            ListNode cur = head;
            for (int num : arr) {
                cur.next = new ListNode(num);
                cur = cur.next;
            }
            lists[i] = head.next;
        }
        return lists;
    }
    public static void traverseList(ListNode head) {
        ListNode cur = head;
        int count = 0;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        System.out.print("[");
        for (cur = head; cur != null;) {
            System.out.print(cur.val);
            count--;
            if (count>0) {
                System.out.print(",");
            }
            cur = cur.next;
        }
        System.out.println("]");
    }
    public static void main(String[] args) {
        Solution s = new Solution();
        int[][] lists = {{1,2,3,4,5},{1},{1,2}};
        int[] n = {2,1,1}; //对应链表的倒数n值
        ListNode[] heads = arraysToLists(lists);
        List<ListNode> res = new ArrayList<>();
        for (int i = 0; i < n.length; i++) {
            res.add(s.removeNthFromEnd(heads[i], n[i]));
            traverseList(res.get(i));
        }
    }
}

输出:

[1,2,3,5]

[]

[1]


3. 合并区间

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]

输出:[[1,6],[8,10],[15,18]]

解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入:intervals = [[1,4],[4,5]]

输出:[[1,5]]

解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。


提示:

  • 1 <= intervals.length <= 10^4
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 10^4

出处:

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

代码:

import java.util.*;
public class mergeIntervals {
    public static class Solution {
        public int[][] merge(int[][] intervals) {
            List<int[]> res = new ArrayList<>();
            if (intervals == null) {
                return res.toArray(new int[0][]);
            }
            Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
            int i = 0;
            int left = 0;
            int right = 0;
            while (i < intervals.length) {
                left = intervals[i][0];
                right = intervals[i][1];
                while (i < intervals.length - 1 && right >= intervals[i + 1][0]) {
                    i++;
                    right = Math.max(right, intervals[i][1]);
                }
                res.add(new int[] { left, right });
                i++;
            }
            return res.toArray(new int[0][]);
        }
    }
    public static void PrintArrays(int[][] arr) {
        System.out.print("[");
        for (int i = 0; i < arr.length; i++) {
            System.out.print("[");
            for (int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j]);
                if (j < arr[i].length - 1) {
                    System.out.print(",");
                }
            }
            System.out.print("]");
            if (i < arr.length - 1) {
                System.out.print(",");
            }
        }
        System.out.println("]");
    }
    public static void main(String[] args) {
        Solution s = new Solution(); 
        int[][] intervals = {{1,3},{2,6},{8,10},{15,18}};
        PrintArrays(s.merge(intervals));
        int[][] intervals2 = {{1,4},{4,5}};
        PrintArrays(s.merge(intervals2));
    }
}

输出:

[[1,6],[8,10],[15,18]]

[[1,5]]


🌟 每日一练刷题专栏 🌟

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

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

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

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

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


目录
相关文章
|
5月前
|
机器学习/深度学习 算法
24. 两两交换链表中的节点, 19.删除链表的倒数第N个节点 ,面试题 02.07. 链表相交
1. **两两交换链表中的节点**:通过引入虚拟头结点,使所有节点都能采用统一的交换逻辑,避免对头结点单独处理。 2. **删除链表的倒数第N个节点**:利用双指针技巧,让快慢指针保持N个节点的距离,当快指针到达末尾时,慢指针正好指向待删除节点的前一个节点。 3. **链表相交**:先计算两链表长度并调整起点,确保从相同距离末尾的位置开始遍历,从而高效找到相交节点或确定无交点。 以上方法均在时间复杂度和空间复杂度上进行了优化,适合用于理解和掌握链表的基本操作及常见算法设计思路。
|
算法
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
256 1
链表的中间结点
链表的中间结点
376 57
|
存储 算法 搜索推荐
链表的中间结点
【10月更文挑战第24天】链表的中间结点是链表操作中的一个重要概念,通过快慢指针法等方法可以高效地找到它。中间结点在数据分割、平衡检测、算法应用等方面都有着重要的意义。在实际编程中,理解和掌握寻找中间结点的方法对于解决链表相关问题具有重要价值。
277 1
Leetcode第十九题(删除链表的倒数第N个节点)
LeetCode第19题要求删除链表的倒数第N个节点,可以通过快慢指针法在一次遍历中实现。
186 0
Leetcode第十九题(删除链表的倒数第N个节点)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
166 0
【LeetCode 09】19 删除链表的倒数第 N 个结点
【LeetCode 09】19 删除链表的倒数第 N 个结点
191 0
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
191 5
LeetCode第19题删除链表的倒数第 N 个结点
该文章介绍了 LeetCode 第 19 题删除链表的倒数第 N 个结点的解法,通过使用快慢双指针,先将快指针移动 n 步,然后快慢指针一起遍历,直到快指针到达链尾,从而找到倒数第 N 个结点的前一个结点进行删除,同时总结了快慢指针可减少链表遍历次数的特点。
LeetCode第19题删除链表的倒数第 N 个结点