代码随想录Day6 | 242.有效的字母异位词 |349. 两个数组的交集 | 202. 快乐数 | 1. 两数之和

代码随想录Day6 | 242.有效的字母异位词 |349. 两个数组的交集 | 202. 快乐数 | 1. 两数之和

242.有效的字母异位词

题目: 给定两个字符串 st ,编写一个函数来判断t是否是s的字母异位词。

​ *注意:*若 s t 中每个字符出现的次数都相同,则称 s t 互为字母异位词。

思路: 统计两个字符串中字母的出现的频率,如果频率相同那么为字母异位词。可以使用一个哈希表来统计词频,但是我们注意字母只有26个,我们可以使用一个长度为26的数组来统计,初始化数组为0,首先遍历s,在对应的字母的位置+1,然后遍历t在字母对应的位置-1,最后如果该数组所有位置均为0,那么s和t则为字母异位词。

代码:

class Solution {
    public boolean isAnagram(String s, String t) {
        int[] fre = new int[26];
        for(int i = 0; i < s.length(); i++){
            fre[s.charAt(i) - 'a']++;
        }
        for(int i = 0; i < t.length(); i++){
            fre[t.charAt(i) - 'a']--;
        }
        for(int i = 0; i < fre.length; i++){
            if(fre[i] != 0 ) return false;
        }
        return true;
    }
}

时间复杂度:O(n),空间复杂度O(n)

349. 两个数组的交集

题目: 给定两个数组 nums1nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序

思路: 暴力解法:两个for循环,记录重复的元素,时间复杂度O(n**2)。哈希表:使用两个哈希表,先循环遍历其中一个数组,将所有元素添加到哈希表中,然后遍历第二个数组,只有第一个哈希表中含有的元素才会存入到第二个哈希表中。

代码:

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        HashSet<Integer> set1 = new HashSet<>();
        HashSet<Integer> set2 = new HashSet<>();
        for(Integer num : nums1){
            set1.add(num);
        }
        for(Integer num : nums2){
            if(set1.contains(num)){
                set2.add(num);
            }
        }
        //将set转化成数组
        return set2.stream().mapToInt(x -> x).toArray();
    }
}

时间复杂度:O(n),空间复杂度O(n)

202. 快乐数

题目: 编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

​ 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
​ 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
​ 如果这个过程 结果为 1,那么这个数就是快乐数。
​ 如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

思路: 快乐数的判断的一个关键是如果每一轮计算出来的值有重复的,那么这个计算就会陷入死循环,就一定不是快乐数,那么我们的判断就很简单了,将每一轮的计算结果放入一个set中,如果计算出重复的值返回false,否则就一直计算,直到计算结果为1或者计算结果重复。

代码:

每次都进行数据类型转换,效率较低。

class Solution {
    public boolean isHappy(int n) {
        Set<Integer> set = new HashSet<>();
        set.add(n);
        while(true){
            int sum = 0;
            for(char num : (n + "").toCharArray()){
                sum += Math.pow(Integer.parseInt(num + ""), 2);
            }
            if(sum == 1) return true;
            if(!set.contains(sum)) set.add(sum);
            else return false;
            n = sum;
        }
    }
}

对10取余,可以得到最后一个数的值。

class Solution {
    public boolean isHappy(int n) {
        Set<Integer> set = new HashSet<>();
        set.add(n);
        while(true){
            int sum = 0;
            while(n > 0){
                sum += Math.pow(n % 10, 2);
                n = n / 10;
            }
            if(sum == 1) return true;
            if(!set.contains(sum)) set.add(sum);
            else return false;
            n = sum;
        }
    }
}

因为轮次不确定,因此无法计算时间复杂度和空间复杂度

1. 两数之和

题目: 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

思路: 这道题用set的话会非常麻烦,因为返回值是索引值而不是数值,采用set的话还要遍历获取索引。采用map的方法,key存放num[i],value存放i,可以直接获取到索引值。遇到一个值,先判断此时map里面有没有和该值相加为target的值,如果有,则返回这两个值的索引,没有,则将该值和其索引放入到map中。

代码:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] res = new int[2];
        Map<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < nums.length; i++){
            int tmp = target - nums[i];
            if(map.containsKey(tmp)){
                res[0] = i;
                res[1] = map.get(tmp);
                return res;
            }
            map.put(nums[i], i);
        }
        return res;
    }
}

时间复杂度:O(n),空间复杂度O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值