剑指 Offer II 032. 有效的变位词(242. 有效的字母异位词)
题目:
思路:
【1】从哈希表的角度入手:本质上这道题考察的就是检验两个字符串的字符是否相等,那么对应字符都是有编码的,根据编码为下标,s串中出现就是加,t串中出现就是减,如果字符是相等的,那么结果必然还是会是0,如果不等那么两个字符串的字符不相等(此外长度不一样一定不相等)。
【2】当然捞一点就是将字符串转为字符数组,进行排序再比较。
代码展示:
排序的方式:
//时间2 ms击败88.26% //内存41.3 MB击败85.9% class Solution { public boolean isAnagram(String s, String t) { if (s.equals(t) || s.length() != t.length()) { return false; } char[] str1 = s.toCharArray(); char[] str2 = t.toCharArray(); Arrays.sort(str1); Arrays.sort(str2); return Arrays.equals(str1, str2); } }
哈希表的方式:
//时间4 ms击败45.68% //内存41.2 MB击败95.56% class Solution { public boolean isAnagram(String s, String t) { //注意看题目允不允许相同 if (s.equals(t) || s.length() != t.length()) return false; //这里由于ASCII码比较齐全,如果仅限26个小写的话可以设置为26 //那么对应下标的地方应该改为 字符 - 'a' int[] flag = new int[256]; for (int i = 0; i < s.length(); i++){ flag[s.charAt(i)]++; flag[t.charAt(i)]--; } for (int x : flag){ if (x != 0) return false; } return true; } }
思路相同为何会存在效率差:
//时间1 ms击败100% //内存42.4 MB击败19.72% class Solution { public boolean isAnagram(String s, String t) { int[] ans = new int[26]; for (char c : s.toCharArray()) { ans[c - 'a'] += 1; } for (char c : t.toCharArray()) { ans[c - 'a'] -= 1; } for (int num : ans) { if (num != 0) { return false; } } return true; } }
对于进阶(Unicode 是为了解决传统字符编码的局限性而产生的方案,它为每个语言中的字符规定了一个唯一的二进制编码。而 Unicode 中可能存在一个字符对应多个字节的问题,为了让计算机知道多少字节表示一个字符,面向传输的编码方式的 UTF−8 和 UTF−16 也随之诞生逐渐广泛使用)【所以思路还是可以的就是要改为使用Map的方式】如:
//时间15 ms击败16.18% //内存42.4 MB击败5.87% class Solution { public boolean isAnagram(String s, String t) { if (s.equals(t) || s.length() != t.length()) { return false; } Map<Character, Integer> table = new HashMap<Character, Integer>(); for (int i = 0; i < s.length(); i++) { char ch = s.charAt(i); table.put(ch, table.getOrDefault(ch, 0) + 1); } for (int i = 0; i < t.length(); i++) { char ch = t.charAt(i); table.put(ch, table.getOrDefault(ch, 0) - 1); if (table.get(ch) < 0) { return false; } } return true; } }