力扣刷题【哈希表篇】

文章目录

  • 一、LeetCode438. 找到字符串中所有字母异位词:
    • 题目链接:
    • 解题思路:
    • 语法细节:
    • 代码实现如下:
  • 二、LeetCode202. 快乐数:
    • 题目链接:
    • 解题思路:
    • 代码实现如下:
  • 三、LeetCode15. 三数之和:
    • 题目链接:
    • 解题思路:
    • 代码实现如下:

一、LeetCode438. 找到字符串中所有字母异位词:

力扣刷题【哈希表篇】_第1张图片

题目链接:

力扣 438 找到字符串中所有字母的异位词 链接: link

解题思路:

用到滑动窗口的思想,在窗口中通过统计小写字母的个数来判断,因为每次只移动一个字母,所以可以用两个指针动态的维护这个窗口。

语法细节:

<1> 两个vector可以直接进行比较;

代码实现如下:

  • 双指针算法 O(n)
	class Solution {
public:
    vector<int> findAnagrams(string s, string p) {

    vector<int> ans;

    if (s.size() < p.size())
        return ans;
    
    // 1. 先待匹配统计窗口中的字母
    vector<int> count(26);
    for (int i = 0; i < p.size(); i ++) {
        count[p[i] - 'a']++;
    }

    // 2. 统计刚开始的过程中移动窗口中的字母
    vector<int> curCounts(26);
    for (int i = 0; i < p.size() - 1; i ++)   // 少统计一个是为了方便后面的操作
    {   
        curCounts[s[i] - 'a'] ++;
    }

    // 3. 开始移动窗口
    for (int left = 0, right = p.size() - 1; right < s.size(); left ++)
    {
        curCounts[s[right] - 'a'] ++;

        if (curCounts == count)
            ans.push_back(left);

        curCounts[s[left] - 'a'] --;

        right ++;
    }
    return ans;
    }
};

二、LeetCode202. 快乐数:

力扣刷题【哈希表篇】_第2张图片

题目链接:

力扣 202 快乐数 链接: link

解题思路:

多写几组测试数据,然后再从数据分析可知,如果重复出现一个数就出现了循环,则此时肯定不是快乐数。
那么如何判断出现了重复数字呢 ?
用快慢指针,一个指针一次走一步,另外一个指针一次走两步,两个指针相遇,即出现了重复数字。
力扣刷题【哈希表篇】_第3张图片

代码实现如下:

  • 双指针算法 O(log n)
class Solution {
public:

    // 1. 得到数n 每位数字的平方和
    int get(int n)
    {
        int sum = 0;
        while(n)
        {
            int k = n % 10;
            sum += k * k;
            n /= 10;
        }
        return sum;
    }

    bool isHappy(int n) {
    
        int slow = get(n), fast = get(get(n));

        int sum = n;
        while (slow != fast)
        {
            slow = get(slow);	// 一次走一步
            fast = get(get(fast));	// 一次走两步
        }
        return slow == 1;
    }
};

三、LeetCode15. 三数之和:

力扣刷题【哈希表篇】_第4张图片

题目链接:

力扣 15 三数之和 链接: link

解题思路:

先对数组进行排序,然后枚举 i出现的情况,然后再用两个指针来控制 jk,注意,要对i,j,,k,进行去重。

代码实现如下:

  • 双指针算法 O(n^2)
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {

    // 思路:求的是数值所以可以用`双指针`,该题的难点在于去重
    vector<vector<int>> res;

    sort(nums.begin(), nums.end());     

    for (int i = 0; i < nums.size(); i ++)
    {
        if (nums[i] > 0)
            break;
        
        // 1. 先对 i 去重
        if (i > 0 && nums[i] == nums[i - 1])
            continue;   

        int left = i + 1, right = nums.size() - 1;

        while (left < right)
        {
           if (nums[i] + nums[left] + nums[right] > 0)
              right--;
           else if (nums[i] + nums[left] + nums[right] < 0)
              left ++;
           else 
            {   
                res.push_back({nums[i], nums[left], nums[right]});
        // 2. 对 left 和 right 两个指针去重
                while (left < right && nums[left] == nums[left + 1])
                    left ++;
                while (left < right && nums[right] == nums[right - 1])
                    right --;

                left ++, right --;
            }
        }
    }
    return res;
    }
};

你可能感兴趣的:(力扣刷题,leetcode,算法)