哈希表4快乐数、5两数之和

93 阅读2分钟

202.快乐数

202. 快乐数 - 力扣(LeetCode)

代码随想录 (programmercarl.com)

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

「快乐数」 定义为:

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

如果 n

快乐数

就返回 true ;不是,则返回 false

示例 1:

输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

示例 2:

输入:n = 2
输出:false

提示:

  • 1 <= n <= 231 - 1

题解

关键在于,快乐数如果永远变不到1的话,一定是陷入了无限循环,那么就是说,当变换过程中出现了重复的数时,说明这个数一定不是快乐数,针对这一点可以运用哈希表,每次变换后都将结果加入哈希表,如果哈希表中已经存在了,那么直接判定不是快乐数。

class Solution {    public boolean isHappy(int n) {        Set<Integer> exist=new HashSet<>();        while(n>1){            int tmp=0;            while(n>0){                tmp+=(n%10)*(n%10);                n=n/10;            }            if(exist.contains(tmp)){                return false;            }            exist.add(tmp);            n=tmp;        }        return true;    }}

1.两数之和

1. 两数之和 - 力扣(LeetCode)

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值

target

的那 两个 整数,并返回它们的数组下标。

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

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

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1]

示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

提示:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只会存在一个有效答案

题解

暴力解法明显是双循环,时间复杂度为O(n2)

用哈希表可以只遍历两次数组即可找到答案。

首先定义一个哈希表,循环数组,同时将target-当前值加入哈希表,同时再检查当前值是否在哈希表中,若在则把下标加入结果中,然后再遍历一次数组找到另一个答案的下标。

class Solution {    public int[] twoSum(int[] nums, int target) {        int[] ans=new int[2];        Set<Integer> record=new HashSet<>();        int index=0;        int ans1=0;        for(int i=0;i<nums.length;i++){            if(record.contains(nums[i])){                ans[index++]=i;                ans1=i;                break;            }            record.add(target-nums[i]);        }        for(int i=0;i<nums.length;i++){            if(nums[i]==target-nums[ans1]&&i!=ans1){                ans[index]=i;            }        }        return ans;    }}

有个更快的解法用的是HashMap,不知道为什么

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // 创建一个HashMap来记录每个数的索引
        Map<Integer, Integer> numMap = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int complement = target - nums[i];
            // 如果complement在map中,返回答案
            if (numMap.containsKey(complement)) {
                return new int[] { numMap.get(complement), i };
            }
            // 将当前数及其索引存入map
            numMap.put(nums[i], i);
        }
        // 如果找不到答案,抛出异常
        throw new IllegalArgumentException("No two sum solution");
    }
}

问了下chatgpt,原来其实只要遍历一次数组即可,使用HashMap可以不用第二次查找就可以找到另一个数组下标

总结

HashSet运用的更加熟练了,了解了HashMap的用法,准备尝试更难点的题目。