手撕6_滑动窗口_字符串的排列

没有注释的代码如下:

import collections

class Solution(object):
    def checkInclusion(self, s1, s2):
        counter1 = collections.Counter(s1)
        N = len(s2)
        left = 0
        right = len(s1) - 1
        counter2 = collections.Counter(s2[0:right])
        while right < N:
            counter2[s2[right]] += 1
            if counter1 == counter2:
                return True
            counter2[s2[left]] -= 1
            if counter2[s2[left]] == 0:
                del counter2[s2[left]]
            left += 1
            right += 1
        return False

s1 = input()
s2 = input()
s = Solution()
print(s.checkInclusion(s1,s2))

有注释的代码如下:

import collections

class Solution(object):
    def checkInclusion(self, s1, s2):
        # 统计 s1 中每个字符出现的次数
        counter1 = collections.Counter(s1)
        N = len(s2)
        # 定义滑动窗口的范围是 [left, right],闭区间,长度与s1相等
        left = 0
        right = len(s1) - 1
        # 统计窗口s2[left, right - 1]内的元素出现的次数
        counter2 = collections.Counter(s2[0:right])
        while right < N:
            # 把 right 位置的元素放到 counter2 中,即:把 right 位置元素放入窗口中
            counter2[s2[right]] += 1
            # 如果滑动窗口内各个元素出现的次数跟 s1 的元素出现次数完全一致,返回 True
            if counter1 == counter2:
                return True
            # 窗口向右移动前,把当前 left 位置的元素出现次数 - 1,即 从窗口中弹出 left位置的元素
            counter2[s2[left]] -= 1
            # 如果当前 left 位置的元素出现次数为 0, 需要从字典中删除,否则这个出现次数为 0 的元素会影响两 counter 之间的比较
            # 次数为 0 的元素必须要删除掉,不然 counter2 中就会有一个元素 c:0,这个 元素是 counter1 中没有的,counter1中的元素的次数value都是大于0的,不删除这个次数为0的元素,就会让 counter1永远不等于 counter2
            if counter2[s2[left]] == 0:
                del counter2[s2[left]]
            # 窗口向右移动
            left += 1
            right += 1
        return False

s1 = input()
s2 = input()
s = Solution()
print(s.checkInclusion(s1,s2))

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
unique_ptr 是 C++11 标准提供的智能指针,用于管理动态分配的对象。它使用了独占所有权的概念,保证了在不再需要指针时自动释放资源,从而避免了内存泄漏。 unique_ptr 的实现涉及到指针的拷贝和移动语义。下面是一个简单的 unique_ptr 的示例代码: ```cpp template <typename T> class unique_ptr { public: explicit unique_ptr(T* ptr = nullptr) : ptr_(ptr) {} ~unique_ptr() { delete ptr_; } unique_ptr(const unique_ptr&) = delete; // 禁用拷贝构造函数 unique_ptr& operator=(const unique_ptr&) = delete; // 禁用拷贝赋值运算符 unique_ptr(unique_ptr&& other) noexcept : ptr_(other.ptr_) { other.ptr_ = nullptr; } unique_ptr& operator=(unique_ptr&& other) noexcept { if (this != &other) { delete ptr_; ptr_ = other.ptr_; other.ptr_ = nullptr; } return *this; } T& operator*() const { return *ptr_; } T* operator->() const { return ptr_; } T* get() const { return ptr_; } private: T* ptr_; }; ``` 上述代码中,我们定义了一个类模板 `unique_ptr`,它模拟了标准库中的 `std::unique_ptr` 功能。在构造函数中,我们接受一个指针作为参数,并将其保存在 `ptr_` 成员变量中。析构函数负责释放指针所指向的资源。为了遵循独占所有权的原则,我们禁用了拷贝构造函数和拷贝赋值运算符,而使用移动语义来实现赋值操作。`operator*` 和 `operator->` 用于重载解引用操作符,方便使用指针指向的对象。 需要注意的是,上述实现只是一个简单的版 unique_ptr,并没有处理更复杂的边界情况和异常安全性。在实际使用中,建议使用标准库提供的 `std::unique_ptr`,它已经经过了充分测试和优化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值