[Leetcode] 249. Group Shifted Strings

这一题,其实弄明白了诀窍也不会很烦。关键在于说其实每一组结果,都可以提取到一个base case。

理由是这样的,就拿第一组来说,"abc" => "bcd" => "xyz"
其中,一个规律就是 b - a = c - b = d - c = 1。或者x - a = y - b = z - c = 23。也就是说bcd只要左shift一次,就可以是abc, xyz只要左shift 23次,就也可以是abc。 如果我们以字符串的第一个字符为a的字符串为这一组的base case。我们就只需要计算第一个字符和a的距离,你就知道整个字符串左shift多少次可以变成一个组的base case。然后我们用一个哈希表来维护组员。(组员可以不包括base case)

举个例子, abc, efg, bdf, efi

1.abc里,a 和 a 的距离是0,所以该字符串不需要左移,自己就是base case。哈希表里面就有了组abc, 然后成员为abc
2.efg里, e 和 a 的距离是4,所以该字符串需要整体左移4格,然后变成了abc这个base case,然后哈希表的abc组里面添加一个成员 efg
3. bdf,b和a的距离是1, 所以该字符串整体左移1个,变成了ace这个base case,哈希表里多了一个组ace,成员为bdf
4. efi,e和a的距离是4,所以整体左移4次,变成了ace,所以哈希表里的ace组再添加一员猛将efi。

至此添加完毕,每一个组的value部分就是题目所需要的列表解集。再注意一下避免左移过多造成的过范围,所以需要通过加26来避免。给出代码如下:

    public List<List<String>> groupStrings(String[] strings) {
        Map<String, List<String>> strMap = new HashMap<>();
        for (String str : strings) {
            String shiftedKey = _getShiftedString(str);
            if (!strMap.containsKey(shiftedKey)) strMap.put(shiftedKey, new LinkedList<String>());
            strMap.get(shiftedKey).add(str);
        }
        
        return new LinkedList<List<String>>(strMap.values());
    }
    
    private String _getShiftedString(String a) {
        if (a.length() > 0) {
            char[] cArr = a.toCharArray();
            int diff = (int)cArr[0] - 'a';
            cArr[0] = 'a';
            for (int i = 1; i < cArr.length; i++) {
                cArr[i] = (char)(((int)(cArr[i] - 'a') >= diff) ? (int)cArr[i] - diff : (int)cArr[i] - diff + 26);
            }
            
            return new String(cArr);
        } else {
            return a;
        }
    }


 

猜你喜欢

转载自blog.csdn.net/chaochen1407/article/details/81240345
今日推荐