力扣之49异位词(超时优化)

本文博主分享了在LeetCode题目《Group Anagrams》中解决字母异位词组合问题的思路变化。最初采用双重循环导致重复计数,通过引入标志数组和字符串排序简化至Map数据结构。关键在于理解异位词的本质和利用数据结构优化性能。
摘要由CSDN通过智能技术生成

记录一下今天在刷力扣时遇到的问题,原题描述:

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

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

说明:

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

我的思路是:
1、首先对入参strs进行两两检查(即check函数),如果是一个异位词,就将其加入到一个List中,有多少个异位词,该List就做多少次add操作。但双重循环遍历后,我发现一个词被计算了多次,就像[eat,tae,eta]为一个List,[tae,eta]为另一个List,发现问题后,我使用sign这样一个布尔型的标记数组对传入的strs中的每一个串进行标记,如果在第一次遍历中他就已经被识别为异位词,那么他就不需要在考虑。

2、然后就是实现的check函数,我需要对传入的两个串进行检查,如果是异位词返回真,否则返回假。具体的逻辑我卸载了代码注释中。

我是用Java代码提交的,代码如下:

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        //标记位 如果某个串已经被加入到了异位词中 将不在对其进行处理
        boolean[] sign = new boolean[strs.length];
        List<List<String>> con = new ArrayList<>();
        List<String> cur = null;
        for (int i = 0; i < strs.length; i++) {
            //检查是否已经将其加入到了异位List中
            if (!sign[i]) {
                cur = new ArrayList<>();
                cur.add(strs[i]); //第一次遍历必定是需要加入的
                for (int j = i + 1; j < strs.length; j++) {
                    if (Solution.check(strs[i], strs[j])) {
                        sign[j] = true;
                        cur.add(strs[j]);
                    }
                }
                con.add(cur);
            }
        }
        return con;
    }

    /*判断两个字符串是否是异位词
    *
    * 执行逻辑是:遍历source串中每一个字符 在target串中搜寻
    *是否存在该字符,如果不存在直接返回false,如果存在就删除掉,
    *在遍历source串结束后,去检查target的长度,如果相等就可以
    *返回true(说明source中的每个字符都找到了 且和source是异位关系)
    */
    private static boolean check(String source, String target) {
        for (int i = 0; i < source.length(); i++) {
            String s = source.charAt(i) + "";
            if (target.contains(s)) {
                target = target.replaceFirst(s, "");
            } else {
                return false;
            }
        }
        if (target.length() == 0) {
            return true;
        }
        return false;
    }

}

提交之后发现112个案例我过了111个,最后一个串逆天的长,一直超时,始终过不了。

打开后看到最后一个案例后,我的心巴凉巴凉的~
在这里插入图片描述


优化一段时间后,也不见效果,得,看看被人思路呗。

1、首先我们在遍历strs时对其中的每一个串进行排序,目的是检查有没有异位词,如果存在一个异位词,就将其加入到一个容器中。

没了~

就这么简单(我可真菜呢,Map这么实用的工具,硬是抛后脑勺去了,还忙半天写了n行代码,哈哈哈~)。

AC代码如下:

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
       Map<String, ArrayList<String>> container = new HashMap<>();
        for (String s : strs) {
            char[] chars = s.toCharArray();
            Arrays.sort(chars);
            //检查容器中是否存在这样一个异位词
            String cur = String.valueOf(chars);
            if (!container.containsKey(cur)) {
                container.put(cur, new ArrayList<>());
            }
            //是第一个词或者是一个异位词 加入到value中
            container.get(cur).add(s);
        }
        return new ArrayList<>(container.values());
    }

}

原题链接:https://leetcode-cn.com/problems/group-anagrams

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值