LeetCode Day11 哈希表

202 快乐数

题目理解

何为快乐数,一个正整数,每次将该数替换为各个位置数字的平方和,循环直到该数变为1,则为快乐数,若无限循环变不为1,则不是快乐数。

思路

题目说了可能会无限循环变不为1,则说明在每次循环的过程中,可能会存在平方和在前一时刻已经出现过,这样就会陷入无限循环,说明不是快乐数。
那么问题就变成了:①求平方和②判断平方和是否出现过。
判断的方法可以使用哈希数组,也可使用快慢指针。

代码

哈希数组

class Solution {
public:
    int getSum(int n) {
        int sum = 0;
        while (n) {
            int a = n % 10;
            n /= 10;
            sum += a * a;
        }
        return sum;
    }
    bool isHappy(int n) {
        unordered_set<int> s;
        int num = n;
        while (num != 1) {
            s.insert(num);
            num = getSum(num);
            if (s.find(num) != s.end())
                return false;
        }
        return true;
    }
};

快慢指针

class Solution {
public:
    int getSum(int n) {
        int sum = 0;
        while (n) {
            int a = n % 10;
            n /= 10;
            sum += a * a;
        }
        return sum;
    }
    bool isHappy(int n) {
        int slow = n, fast = n;
        do {
            slow = getSum(slow);
            fast = getSum(fast);
            fast = getSum(fast);
        } while(slow != fast);
        if (slow == 1)
            return true;
        return false;
    }
};

1 两数之和

思路

要寻找和为target的两个数,即遍历数组,寻找值为i ,target-i这两个数的下标即可,使用哈希表查找元素时间复杂度仅为O(1)。

代码

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> num;
        for(int i = 0;i < nums.size();i++) {
            if(num.find(target - nums[i]) != num.end()) {//避免数组同一元素使用两次,因此先进行判断再添加到哈希表中。
                return {i,num[target - nums[i]]};
            }
            num.insert({nums[i],i});
        }
        return {};
    }
};

454 四数相加 Ⅱ

思路

将四个数组分为两部分,一部分为A+B,存在哈希表中(key为两数之和,value为此和出现次数),另一部分为C+D,则判断四数之和是否为0,变为了寻找哈希表中,0-(C+D)是否存在。

代码

class Solution {
public:
    int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
        unordered_map<int,int> sum2;
        int count=0;
        for(auto a:A)
            for(auto b:B)
                ++sum2[a+b];
        for(auto c:C)
            for(auto d:D) {
                if(sum2[0-(c+d)]>0)
                {
                    count+=sum2[0-(c+d)];
                }
            }
        return count;
    }
};

383 赎金信

思路

寻找magazine是否包含ransom,而且两个字符串均由小写字母构成,因此可以用一个长度为26的数组来记录magazine中字符出现的子数,遍历ransom,判断各字符在哈希表中的值即可。

代码

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int c[26] = {0};
        for (auto i : magazine) {
            ++c[i - 'a'];
        }
        for (auto i : ransomNote) {
            if (c[i - 'a'] > 0)
                --c[i - 'a'];
            else return false;
        }
        return true;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值