Java算法 字母异位词分组 、最长连续序列

小王的Java刷题日记Day5

记录刷题过程,作为笔记和分享,坚持每天刷题,每天进步,编程语言为Java。

题目一:字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

例如:

输入: strs = ["see", "ese", "say", "ees", "asy", "baa"]
输出: [["baa"],["say","asy"],["see","ese","ees"]]

思路:    哈希表存储排序后进行比较                        时间复杂度:O(nklog⁡k)

1、两个字符串互为字母异位词,当且仅当两个字符串包含的字母相同。

2、同一组字母异位词中的字符串具备相同点,可以使用相同点作为一组字母异位词的标志,使用哈希表存储每一组字母异位词,哈希表的键为一组字母异位词的标志,哈希表的值为一组字母异位词列表。

3、遍历每个字符串,对于每个字符串,得到该字符串所在的一组字母异位词的标志,将当前字符串加入该组字母异位词的列表中。遍历全部字符串之后,哈希表中的每个键值对即为一组字母异位词。

4、由于互为字母异位词的两个字符串包含的字母相同,因此对两个字符串分别进行排序之后得到的字符串一定是相同的,故可以将排序之后的字符串作为哈希表的键。

5、具体更加详细的解释已经注解在代码块中。

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        // 创建一个哈希表,键是排序后的字符串,值是原始字符串的列表
        Map<String, List<String>> hashMap = new HashMap<String, List<String>>();
        // 遍历输入的字符串数组
        for (String str : strs) { //循环遍历数组 strs 中的每个元素,将当前元素赋值给变量 str,然后执行循环体内的操作。
            char[] array = str.toCharArray();    // 将字符串转换为字符数组,并对字符数组进行排序
            Arrays.sort(array);
            // 将排序后的字符数组转换为字符串,作为哈希表的键
            String key = new String(array);
            // 获取键对应的值,如果键不存在则创建一个新的空列表
            List<String> list = hashMap.getOrDefault(key, new ArrayList<String>());
            // 将当前字符串添加到列表中
            list.add(str);
            // 更新哈希表中的键值对
            hashMap.put(key, list);
        }
        // 返回哈希表中的值,即每个组中的字符串列表
        return new ArrayList<List<String>>(hashMap.values());
    }
}

注:

时间复杂度:O(nklog⁡k),其中 n 是 strs中的字符串的数量,k 是 strs中的字符串的的最大长度。需要遍历 n个字符串,对于每个字符串,需要 O(klog⁡k)的时间进行排序以及 O(1)的时间更新哈希表,因此总时间复杂度是 O(nklog⁡k)。

题目二:最长连续序列

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。    请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

例如:

输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。

思路: 哈希表

排序的话时间复杂度会超出题目要求,所以考虑哈希表。

1使用 HashSet 存储数组中的元素,以便快速查找

2、记录最长连续序列的长度

3、遍历 HashSet 中的每个元素,如果当前元素的前一个元素不在 HashSet 中,说明当前元素是一个连续序列的起始点。

4、继续向后查找,直到不再连续为止

5、更新最长连续序列的长度

6、返回最长连续序列的长度

public class Solution {
    // 找出数组中最长的连续序列的长度
    public int longestConsecutive(int[] nums) {
        // 使用 HashSet 存储数组中的元素,以便快速查找
        Set<Integer> num_set = new HashSet<Integer>();
        for (int num : nums) {
            num_set.add(num);
        }

        // 记录最长连续序列的长度
        int longestStreak = 0;

        // 遍历 HashSet 中的每个元素
        for (int num : num_set) {
            // 如果当前元素的前一个元素不在 HashSet 中,说明当前元素是一个连续序列的起始点
            if (!num_set.contains(num - 1)) {
                int currentNum = num;
                int currentStreak = 1;

                // 继续向后查找,直到不再连续为止
                while (num_set.contains(currentNum + 1)) {
                    currentNum += 1;
                    currentStreak += 1;
                }

                // 更新最长连续序列的长度
                longestStreak = Math.max(longestStreak, currentStreak);
            }
        }

        // 返回最长连续序列的长度
        return longestStreak;

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值