代码随想录算法训练营第六天 | 242. 有效的字母异位词、349. 两个数组的交集、202.快乐数、1. 两数之和

242. 有效的字母异位词

res[26] ;

++

--

00

判断两个单词是否字母 出现的次数都相同,因为字母只有26个小写的,所以可以考虑用数组当hash表,并且可以确定每个字母的位置(当前字母-'a'用作数组下标),第一个单词中所有字母出现的次数,应该与第二个字母的相等(res[a]++;  res[b]--;)
res[26]这个数组中所有的数字都清零了证明都是相同的,否则不成立。

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

        return true;
    }

349. 两个数组的交集

思路:

O(n^2) 方法就是暴力解决,需要求数组交集的情况下,可以把第一个数组变成哈希表1,减少遍历,因为只看两个数组中都重复出现的次数,再用哈希表2存哈希表1中存储过的数据,

if(hash1.contains(i)){

hash2.add(i);

}

最后返回的是数组,遍历一遍表2存储结果;

    public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> exist=new HashSet<Integer>();
        Set<Integer> rese=new HashSet<Integer>();

        for(int i=0;i<nums1.length;i++){
            exist.add(nums1[i]);
        }

        for(int i=0;i<nums2.length;i++){
            if(exist.contains(nums2[i])){
                rese.add(nums2[i]);
            }
        }

        int j=0;
        int[] res=new int[rese.size()];
        for(Integer i:rese){
            res[j++]=i;
        }

        return res;
    }

202.快乐数

二刷思路:先计算每次的结果(按位取平方),总体循环退出条件是 (无限循环或者是就是1)这两种情况都需要终止循环,最终以是否是1判断true or false.

核心思路先是肯定了这其中一定有一个按位拆分,计算平方和的函数,n/10 循环变量,n%10是没位的数字,

public int getNext(int n) {

        int sum = 0;
        while (n > 0) {
            sum += (n % 10) * (n % 10);
            n /= 10;
        }

        return sum;
    }

怎么计算一定能是快乐数呢?

我们猜测会有以下三种可能。

  1. 最终会得到 1。
  2. 最终会进入循环。
  3. 值会越来越大,最后接近无穷大。

第三个情况比较难以检测和处理。我们怎么知道它会继续变大,而不是最终得到 1 呢?我们可以仔细想一想,每一位数的最大数字的下一位数是多少。

对于 3 位数的数字,它不可能大于 243。这意味着它要么被困在 243 以下的循环内,要么跌到 1。4 位或 4 位以上的数字在每一步都会丢失至少1位,直到降到 3 位为止。所以我们知道,最坏的情况下,算法可能会在 243 以下的所有数字上循环,然后回到它已经到过的一个循环或者回到 1。但它不会无限期地进行下去,所以我们排除第三种选择。

哈希表用于存储已经出现过的中间数字,最后结果可能是无限循环,也可能是取到1了,所以要判断一下。

public boolean isHappy(int n) {
        Set<Integer> exist = new HashSet<Integer>();

        while (n != 1 && !exist.contains(n)) {
            exist.add(n);
            n = getNext(n);
        }

        return n == 1;
    }

1. 两数之和

回到梦开始的地方了,我一直都是暴力解决的,所以甚至对哈希表的解法没什么印象,对时间空间复杂度也没什么追求,可以用set解决,也可以用map解决。

set需要多遍历一次。

public int[] twoSum(int[] nums, int target) {
        int[] res=new int[2];
        Set<Integer> gap=new HashSet<Integer>();

        Boolean check=false;
        for(int i=0;i<nums.length;i++){
            if(gap.contains(nums[i])){
                res[1]=i;
                check=true;
                break;
            }else{
                gap.add(target-nums[i]);
            }
        }

        for(int i=0;i<res[1];i++){
            if(nums[i]==target-nums[res[1]]){
                res[0]=i;
                break;
            }
        }

        return res;


    }

map解决相对方便一些

    public int[] twoSum(int[] nums, int target) {
        //hash表存之后的数据
        //<数值,下标>
        int n=nums.length;
        Map<Integer,Integer> exist=new HashMap<Integer,Integer>();
        for(int i=0;i<n;i++){
            if(exist.containsKey(target-nums[i])){
                return new int[]{exist.get(target-nums[i]),i};
            }
            else{
                exist.put(nums[i],i);
            }
        }
        return new int[0];
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值