力扣热题100

排序

力扣热题100_第1张图片

快速排序

哈希

1.两数之和

class Solution {
public:
    vector twoSum(vector& nums, int target) {
        // 
        unordered_map hashtable;
        
        for (int i = 0; i < nums.size(); ++i) {
            // 看能否找到 nums[i],it返回索引
            auto it = hashtable.find(target - nums[i]);
            if (it != hashtable.end()) {
                // 如果能找到
                return {it->second, i};
            }
            // 记录每个数字的索引
            hashtable[nums[i]] = i;
        }
        return {};
    }
};

2. 49 字母异位词

class Solution:
    def groupAnagrams(self, strs):
        mp = {}
        for str in strs:
            # sorted 后是个列表,需要''.join一下
            key = ''.join(sorted(str))
            if key not in mp:
                # 第一次遍历到,就创建一个[]
                mp[key] = []
            mp[key].append(str)

        ans = []
        for value in mp.values():
            ans.append(value)
        return ans

3. 128 最长连续序列

class Solution {
public:
    int longestConsecutive(vector& nums) {
        // 不重复的集合
        unordered_set num_set;
        
        for (const int& num : nums) {
            num_set.insert(num);
        }

        int longestStreak = 0;
        for (const int& num : num_set) {
            // 找前一位
            if (!num_set.count(num - 1)) {
                // 设置起始数字
                int currentNum = num;
                // 长度初始化为 1
                int currentStreak = 1;
                // 只要能找到下一个位置的数
                while (num_set.count(currentNum + 1)) {
                    currentNum += 1;
                    currentStreak += 1;
                }
                // 更新最长长度
                longestStreak = max(longestStreak, currentStreak);
            }
        }
        return longestStreak;
    }
};

双指针

283 移动0

class Solution {
public:
    void moveZeroes(vector& nums) {
        int indexNow = 0;  // 赋值
        int indexNum = 0;
        int m = nums.size();

        // 初始化双指针指向 index 0
        // indexNum 扫描是否为 0
        // 如果不为 0 就交换,并递增 Now(始终指向0)
        // 如果为 0,递增indexNum (始终指向非0,或下一个元素)
        while(indexNum < m) {
            if (nums[indexNum] != 0) {
                nums[indexNow++] = nums[indexNum]; 
            }
            ++indexNum;
        }

        for (int i = indexNow; i < m; i++) {
            nums[i] = 0;
        }
    }
};

11 盛水最多的容器

class Solution {
public:
    int maxArea(vector& height) {
        int l = 0, r = height.size() - 1;
        
        int maxV = 0;
        while (l < r) {
            int len = r - l;
            maxV = max(min(height[l], height[r]) * len, maxV);
            // 收缩小的那一边
            if (height[l] <= height[r]) {
                ++l;
            } else {
                --r;
            }
        }
        return maxV;
    }
};

15 三数之和

class Solution:
    def threeSum(self, nums):
        # 对数组进行排序
        nums.sort()
        n = len(nums)
        res = []

        # 遍历数组,以first作为第一个元素的指针
        for first in range(n):
            # 跳过重复元素,避免重复解
            if first >= 1 and nums[first] == nums[first - 1]:
                continue

            # 初始化第三个元素的指针,从数组末尾开始
            third = n - 1
            # 目标和为当前first元素的相反数
            target = -nums[first]

            # 遍历数组中剩下的元素,以second作为第二个元素的指针
            for second in range(first + 1, n):
                # 跳过重复元素,避免重复解
                if second > first + 1 and nums[second] == nums[second - 1]:
                    continue

                # 调整third指针,使得nums[first] + nums[second] + nums[third]接近于0
                while second < third and nums[second] + nums[third] > target:
                    third -= 1

                # 如果second和third重合,退出循环
                if second == third:
                    break

                # 如果找到满足条件的组合,添加到结果列表中
                if nums[second] + nums[third] == target:
                    res.append([nums[first], nums[second], nums[third]])

        return res

42 接雨水

class Solution {
public:
    int trap(vector& height) {

        // 初始化左右两侧的最大高度
        int leftMax = 0;
        int rightMax = 0;
        int l = 0, r = height.size() - 1;
        int ans = 0;

        while(l < r) {
            // 更新左右两边最大值
            leftMax = max(leftMax, height[l]);
            rightMax = max(rightMax, height[r]);
            // 用高度的较小值更新
            if (height[l] < height[r]) {
                ans += leftMax - height[l];
                l++;
            }else {
                ans += rightMax - height[r];
                r--;
            }
        }
        return ans;

    }
};

滑动窗口

3.无重复字符的最长子串

class Solution:
    def lengthOfLongestSubstring(self, s):
        # 使用一个布尔数组来标记字符是否出现过
        occ = [False] * 200
        n = len(s)
        res = 0

        # 使用滑动窗口的方法,l 和 r 分别表示窗口的左右边界
        l, r = 0, 0
        # 扩展右窗口
        while r < n:
            # 是否循环收缩左窗口?
            # 如果字符 s[r] 在窗口中已存在
            # 则移动左边界 l,直到 s[r] 不在窗口中
            while occ[ord(s[r])] and l < r:
                occ[ord(s[l])] = False
                l += 1
            
            # 标记字符 s[r] 在窗口中出现
            occ[ord(s[r])] = True

            # 更新最大子串长度
            res = max(res, r - l + 1)

            # 移动右边界,扩大窗口
            r += 1

        return res

438 找到字符串中所有字母异位词

class Solution:
    def findAnagrams(self, s, p):
        # 获取字符串 s 和 p 的长度
        m, n = len(s), len(p)
        # 如果 s 比 p 短,返回空列表
        if m < n:
            return []

        # 初始化检查表,记录 p 中每个字符的出现次数
        checkTable = [0] * 26
        for ch in p:
            checkTable[ord(ch) - ord('a')] += 1

        ret = []
        l, r = 0, 0
        while r < m:
            # 移动右指针 r,更新检查表
            checkTable[ord(s[r]) - ord('a')] -= 1

            # 如果某个字符的计数小于0,移动左指针 l,直至计数不小于0
            while checkTable[ord(s[r]) - ord('a')] < 0:
                checkTable[ord(s[l]) - ord('a')] += 1
                l += 1

            # 如果当前窗口大小等于 p 的长度,记录起始位置
            if r - l + 1 == n:
                ret.append(l)

            r += 1

        return ret

你可能感兴趣的:(leetcode,算法,哈希算法)