【leetcode】数据结构—哈希表

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

  • 方法一:利用哈希集合,来找出循环的出口,如果计算后的和在哈希集合中有出现过,就说明出现了循环,永远不可能是快乐数。
class Solution {
public:
    bool isHappy(int n) {
        unordered_set<int> tmp;
        while(n!=1){
            //各位求和
            int ans = 0;
            while(n>0)
            {
                ans += (n%10)*(n%10);
                n = n /10;
            }
            n = ans;
            
            if(tmp.count(n)) return false;
            tmp.insert(n);
        }
        return true;
    }
};
  • 方法二:参考了快慢指针的解法,因为该题归到底也是要判断每次计算的和是否会循环。
class Solution {
public:
    int bitSquareSum(int n) {
        int sum = 0;
        while(n > 0)
        {
            int bit = n % 10;
            sum += bit * bit;
            n = n / 10;
        }
        return sum;
    }
    
    bool isHappy(int n) {
        int slow = n, fast = n;
        do{
            slow = bitSquareSum(slow);
            fast = bitSquareSum(fast);
            fast = bitSquareSum(fast);
        }while(slow != fast);
        
        return slow == 1;
    }
};

解决冲突的方法

  1. 开放定址法:线性探测再散列、二次探测再散列、伪随机探测再散列
  2. 拉链法(705 设计哈希集合)

哈希表+滑动窗口
滑动窗口是数组/字符串问题中常用的方法,和哈希表结合的题目比如3.无重复字符的最长子串这道题用哈希表代替了第二层循环。当 S i , j S_{i,j} 这段字符串没有重复,当新来一个 S j + 1 S_{j+1} 时,不用再像暴力解一样再重新遍历 S i , j + 1 S_{i,j+1} 看是否有重复,只需判断 S j + 1 S_{j+1} 有没有在 S i , j S_{i,j} 出现过就行。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int len = s.size();
        unordered_set<char> tmp;
        int i=0,j=0,res=0;
        while(i<len and j<len){
            if(!tmp.count(s[j])){
                tmp.insert(s[j++]);
                res = max(j-i,res);
            }
            else tmp.erase(s[i++]);
        }
        return res;
    }
};

但其实可以将滑动窗口进行优化,可以将set改为映射,储存下各字符的位置,这样更新i的时候不用加1,而是直接变到重复字符的下一位。

发布了86 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_36530992/article/details/104216845