算法练习Day6| 242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和

#算法#哈希表#leetcode#两数之和

继续今天的练习记录。

目前没有day5的记录,因为我们的计划是每周日休息,但是后面我还是想把这一天补上来,作为前面一周练习的总结,尽量细致记录出错的地方和原因,查缺补漏吧。

今天练习的是哈希表相关的题目,哈希表经常用到,所以对哈希表比较熟悉,而目前算法练习的主要还是利用哈希表的元素唯一这个特性。如果对哈希表还不是很熟悉,可以先学习相关的内容,并不难。

242.有效的字母异位词

题目链接:242. 有效的字母异位词 - 力扣(LeetCode)给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的 字母异位词。

这道题感觉解法很多,我这里用了两种方法。

第一种思路就是把字符串转成字符数组,然后sort,这样如果每一个指针下字符都相同,那就是字母异位词。

第二种就是利用数组,因为单词包含的字符有限,最多26个不同的字母,所以创建数组,通过字符和‘a’运算得到对应的下标,即每个字符对应数组的一个下标,先遍历记录s,数组元素值+1,遍历t,数组元素值-1,如果最终数组值都是0,那就是字母异位词,否则不是。

具体代码:

public boolean isAnagram(String s, String t) {
        if(null == s || null == t) {
            return false;
        }
        if(s.length() != t.length()) {
            return false;
        }
        //解法1 先排序,再同个index判断
        // char[] ss = s.toCharArray();
        // Arrays.sort(ss);

        // char[] tt = t.toCharArray();
        // Arrays.sort(tt);

		// for (int i = 0; i < s.length(); i++) {
		// 	if(ss[i] != tt[i]) {
        //         return false;
        //     }
		// }
        // return true;

        //解法2 同数组记录,因为单词包含的字母只有26个,可穷举
        int[] container = new int[26];
        char[] ss = s.toCharArray();
        for(char c1 : ss) {
            container[c1 -'a']++;
        }
        char[] tt = t.toCharArray();
        for(char c2: tt) {
            container[c2 - 'a']--;
        }

        for(int i = 0; i < 26; i++) {
            if(container[i] != 0) {
                return false;
            }
        }
        return true;

    }

349. 两个数组的交集

题目链接:349. 两个数组的交集 - 力扣(LeetCode)给定两个数组 nums1 和 nums2 ,返回 它们的 交集。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

唯一,不考虑结果顺序,出现这些条件,大部分情况下都是可以通过哈希表来解决。

思路:先将nums1的元素写入哈希表set1,然后遍历nums2数组,如果set1中包含nums2中的元素,将此元素记录到另一个哈希表中,注意这里为了方便,最好是记录到另一个哈希表resSet中,因为nums2中的元素也是可能重复的,这里可以做一次去重。然后将resSet转为数组即可。

具体代码:

public int[] intersection(int[] nums1, int[] nums2) {
        int[] empty = new int[0];
        if(null == nums1 || null == nums2) {
            return empty;
        }
        //用set解决, Java的话就是 HashSet
        Set<Integer> set = new HashSet<>();
        Set<Integer> resSet = new HashSet<>();
        for(int num1 : nums1) {
            set.add(num1);
        }
        for(int num2 : nums2) {
            if(set.contains(num2)) {
                resSet.add(num2);
            }
        }
        if(resSet.size() <= 0) {
            return empty;
        }
        int[] res = new int[resSet.size()];
        Iterator<Integer> it = resSet.iterator();
        int i = 0;
        while (it.hasNext()) {
            res[i] = it.next();
            i++;
        }
        return res;
    }

202. 快乐数 

题目链接:202. 快乐数 - 力扣(LeetCode)

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

「快乐数」 定义为:

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

如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

这道题我个人自己的想法是先计算sum,如果sum是1则返回,sum不是1,则递归。但是这里忽略了一个问题,这个递归很可能是无法退出的。这里还有另一个退出条件就是某一次的和sum之前已经出现过了,那这个数字一定不会是快乐数,所以这个时候就可以退出了。这道题还有一个点就是计算数组和,这个可以记一下,后面可以直接用。

有几个注意的点,sum要更新,n要更新,每次先记录上一次的和。

具体代码:

public boolean isHappy(int n) {
       
        Set<Integer> res = new HashSet<>();
        int sum = n;
        while(1 != sum && !res.contains(sum)) {
            res.add(sum);
            sum = 0;        //重新+的时候这里不能再加之前的sum,得置为0重新计算
            while(n > 0) {
                int num = n%10;
                sum += num * num;
                n = n/10;
            }
            if(1 == sum) {
                return true;
            }
            n = sum;
            
        }
        
        return 1 == sum;
    }

1. 两数之和 

哈哈,终于到你了,梦开始的地方!

但是这道题没时间记录了,我明天会补充,很经典,但是并不难,很多刷leetcode的朋友应该都有提交记录了。

题目链接:1. 两数之和 - 力扣(LeetCode)

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

刚刚将这道题完成了,用两种方法,一种就是第一想法暴力解法,brute force solution,英文是这个么,前两天我看还是另一个词组,有英语比较好的朋友可以评论区说说看。一种是通过hashmap来存值和对应的下标。

暴力解法:两个for循环,将数组里面的数组两两相加,判断和是否是target。

哈希法:创建map,key用来存储数组元素,因为这道题不能使用重复的数字,所以这个特性也可以利用,value用来存储数组下标,遍历数组,如果map里面包含元素与遍历的当前数组元素的和为target,则找到目标值,返回对应的下标即可。

具体代码:

public int[] twoSum(int[] nums, int target) {
        if(null == nums) {
            return null;
        }
        // int length = nums.length;
        // int[] res = new int[2];
        //brute force solution
        // for(int i = 0; i < length; i++) {
        //     for(int j = i+1; j < length; j++) {
        //         if(nums[i] + nums[j] == target) {
        //             res[0] = i;
        //             res[1] = j;
        //         }
        //     }
        // }
        // return res;

        int length = nums.length;
        int[] res = new int[2];
        Map<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < length; i++) {
            int key = target - nums[i];
            if(map.containsKey(key)) {
                Integer v = map.get(key);
                if(null != v) {
                    int vi = v;
                    res[0] = vi;
                    res[1] = i;
                }
            } else {
                map.put(nums[i], i);
            }
        }
        return res;
    }

好了,这篇文章完结,继续下次的锻炼,继续加油!

有疑问或者认为写的有问题的朋友,欢迎留言交流!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值