解决这题,首先可以判断两个字符串长度是否相同,如果不等,则false。判断完字符串长度相等后,需要统计两个字符串中字符出现的次数,在涉及到判断一个元素是否出现过以及出现过几次的问题时,使用哈希法,这里字符是小写字符,一共26个字母,以'a'的ASCII码值为基准,将其余字符与'a'相减,结果一定在0-25中,这里是有限个结果,所以可以用数组进行解决。哈希数组:元素不是直接放入数组中,而是用来判断元素是否出现过,所以数组中的值只有0和1,1所对应的索引即是出现过的元素。使用一个哈希数组来进行判断,同时遍历两个字符串,先将第一个字符串中出现的字符相对应位置加1,然后同时将第二个字符串出现的字符相对应位置减一。最后遍历完看哈希数组是否为0.即可判断
class Solution {
public boolean isAnagram(String s, String t) {
int[] hash=new int[26];
if(s.length()!=t.length()){
return false;
}
for(int i=0;i<s.length();i++){
hash[s.charAt(i)-'a']++;
hash[t.charAt(i)-'a']--;
}
for(int i=0;i<hash.length;i++){
if(hash[i]!=0){
return false;
}
}
return true;
}
}
1.hash数组解法
这里力扣给出了数组元素的范围,所以可以使用哈希数组进行解决。这里使用两个哈希数组,第一个哈希数组在遍历完第一个数组之后,将对应位置的数组元素加1;另一个哈希数组进行同样操作,然后比较两个哈希数组对应位置元素是否大于0(因为一个数组有相同元素,会大于1,这里只用判断大于0出现过这个元素即可),若大于0,则取出元素放入ArrayList中,最后将ArrayList转成数组返回
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
List<Integer> result=new ArrayList<>();
int[] hash1=new int[1002];
int[] hash2=new int[1002];
for(int i=0;i<nums1.length;i++){
hash1[nums1[i]]++;
}
for(int i=0;i<nums2.length;i++){
hash2[nums2[i]]++;
}
for(int i=0;i<1002;i++){
if((hash1[i]>0)&&(hash2[i]>0)){ //大于0,因为可能存在相同元素
result.add(i);
}
}
int[] arr=new int[result.size()];
int index = 0;
for(int i:result){
arr[index++]=i;
}
return arr;
}
}
2.hashset解法
这里假如没有设置数组元素大小范围,则不能使用哈希数组进行解决。这里使用set进行,将一个数组的元素放入set中,然后遍历另一个数组,使用set.contains()方法判断元素是否在上一个数组中出现过,若出现过,则放入一个新的set中。遍历完之后将新的set转成数组返回。
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> set1=new HashSet<>();
Set<Integer> set2=new HashSet<>();
for(int num:nums1){
set1.add(num);
}
for(int num:nums2){
if(set1.contains(num)){
set2.add(num);
}
}
int[] res=new int[set2.size()];
int index=0;
for(int i:set2){
res[index++]=i;
}
return res;
}
}
该题的关键是要读懂题中的无限循环这个词,有循环就意味着有两个相同的值会出现,这里判断一个值是否出现过,就可以用哈希法。这里最适合用set。题中还有一个关键就是求一个数的每一位的平方和,解决这两个问题即可解决本题。
class Solution {
public boolean isHappy(int n) {
Set<Integer> set1=new HashSet<>();
while(n!=1){
int sum=0;
while(n>0){
int digit=n%10;
sum+=digit*digit;
n=n/10;
}
n=sum;
if(set1.contains(n)){
return false;
}
set1.add(n);
}
return true;
}
}
这里两数之和,不能直接去想把两个数组元素相加之后再去与target相比,这样会很复杂。可以转化成读取到了一个值nums[i]时,判断一下之前有没有读取过target-nums[i],这样又转化成了判断一个元素是否出现过的问题,使用哈希法。但是本题需要返回的是索引,不是元素值,而计算需要用到元素值,这里有两个量,于是使用哈希结构中的hashmap,先遍历读取数组,将索引和元素放入map中,每读一个元素判断一次target-元素是否在map中出现过。最后使用map方法根据target-nums[i]返回对应的索引;这里个人理解,需要返回什么值就将其作为value。
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> map=new HashMap<>();
int[] res=new int[2];
for(int i=0;i<nums.length;i++){
if(map.containsKey(target-nums[i])){
res[0]=i;
res[1]=map.get(target-nums[i]);
}
map.put(nums[i],i);
}
return res;
}
}