leetcode76

目录

803ms超时。。。。越改越超时。。。

一些纠缠

代码分析:

代码问题:

改进建议:

示例代码:

The error message you’re seeing indicates that there is a reference binding to a null pointer in your code. This typically happens when you try to access an element of a vector that has not been initialized or has been moved from.

问题分析:

修正后的代码:

解释:

c_++可以在函数里定义函数吗

int& a;int &a;int & a;int&a;还有int* a四种形式。哪些是对的

解释:

注意事项:

示例:

int*a,int * a,int* a,int *a哪些是对的

解释:

注意事项:

示例:

bool check() { for (const auto &p: ori) { if (cnt[p.first] < p.second) { return false; } } return true; } 。这边可以写成p->first吗

.和->在什么时候使用

.运算符(点运算符):

->运算符(箭头运算符):

比较:

注意事项:

示例:使用迭代器

bool check() { for (const auto &p: ori) { if (cnt[p.first] < p.second) { return false; } } return true; } const能删去吗

如果可以删除 const 的情况:

保留 const 的好处:

示例:

结论:

--c++-------------------------

 

1. 使用迭代器

2. 使用基于范围的for循环(C++11及以后)

3. 使用C++17结构化绑定(C++17及以后)

4. 使用std::for_each算法

1. 使用clear()成员函数

2. 使用迭代器手动删除

3. 赋值一个空map

4. 使用swap()方法


803ms超时。。。。越改越超时。。。

class Solution {
public:

// //题解说封装
// bool check(int l,int r)
// {

// }

    string minWindow(string s, string t) {
        int ls=s.size();int lt=t.size();
        if(ls<lt)return "";if(s==t)return t;

        vector<int> hilight;
        unordered_map<char,int> mp;unordered_map<char,int> mp1;
        for(int i =0;i<lt;i++)mp[t[i]]++;
        for(int i =0;i<ls;i++)if(mp[s[i]])hilight.push_back(i);
        if(hilight.empty()) return "";


        int left=0;int right=0;mp1[s[hilight[0]]]=1;
        int len=ls;int ansl,ansr;int F=0;
        while(left<=right&&right<hilight.size())
        {
            // for(int i=left;i<=right;i++)mp1[s[hilight[i]]]++;
            int flag=0;
            for(auto it=mp.begin();it!=mp.end();it++)
            if(it->second>mp1[it->first]){flag=1;right++;
            if(left<=right&&right<hilight.size())mp1[s[hilight[right]]]++;
            break;}
            if(!flag)
            {
              cout<<"left:"<<left<<"right:"<<right<<endl;
             if(len>=hilight[right]-hilight[left]+1)
            {F=1;len=hilight[right]-hilight[left]+1;ansl=hilight[left];ansr=hilight[right];cout<<"len:"<<len<<endl;}  
            mp1[s[hilight[left]]]--;left++;
            }

            //mp1.clear();

        }cout<<ansl<<ansr;
        if(F)return s.substr(ansl,ansr-ansl+1);else return "";



        
    }
};

我啥也没动啊,吧改的部分删了,又过了。。

class Solution {
public:

// //题解说封装
// bool check(int l,int r)
// {

// }

    string minWindow(string s, string t) {
        int ls=s.size();int lt=t.size();
        if(ls<lt)return "";if(s==t)return t;

        vector<int> hilight;
        unordered_map<char,int> mp;unordered_map<char,int> mp1;
        for(int i =0;i<lt;i++)mp[t[i]]++;
        for(int i =0;i<ls;i++)if(mp[s[i]])hilight.push_back(i);
        if(hilight.empty()) return "";


        int left=0;int right=0;mp1[s[hilight[0]]]=1;
        int len=ls;int ansl,ansr;int F=0;
        while(left<=right&&right<hilight.size())
        {
            // for(int i=left;i<=right;i++)mp1[s[hilight[i]]]++;
            int flag=0;
            for(auto it=mp.begin();it!=mp.end();it++)
            if(it->second>mp1[it->first]){flag=1;right++;
            if(left<=right&&right<hilight.size())mp1[s[hilight[right]]]++;
            break;}
            if(!flag)
            {
              //if(hilight[right]-lt<(hilight[left]+hilight[right])/2)
 //{
                if(len>=hilight[right]-hilight[left]+1)
            {F=1;len=hilight[right]-hilight[left]+1;ansl=hilight[left];ansr=hilight[right];cout<<"len:"<<len<<endl;}  
            mp1[s[hilight[left]]]--;left++;

                }
            }
         if(F)return s.substr(ansl,ansr-ansl+1);else return "";
           }

            //mp1.clear();

        



        
    };

因为我删除了cout节省了时间???

这是官方题解,时间复杂度和我都是O(N),合理怀疑是我的变量太多了,设置高亮标记反而不如老老实实一步步走。。

class Solution {
public:
    unordered_map <char, int> ori, cnt;

    bool check() {
        for (const auto &p: ori) {
            if (cnt[p.first] < p.second) {
                return false;
            }
        }
        return true;
    }

    string minWindow(string s, string t) {
        for (const auto &c: t) {
            ++ori[c];
        }

        int l = 0, r = -1;
        int len = INT_MAX, ansL = -1, ansR = -1;

        while (r < int(s.size())) {
            if (ori.find(s[++r]) != ori.end()) {
                ++cnt[s[r]];
            }
            while (check() && l <= r) {
                if (r - l + 1 < len) {
                    len = r - l + 1;
                    ansL = l;
                }
                if (ori.find(s[l]) != ori.end()) {
                    --cnt[s[l]];
                }
                ++l;
            }
        }

        return ansL == -1 ? string() : s.substr(ansL, len);
    }
};

作者:力扣官方题解
链接:https://leetcode.cn/problems/minimum-window-substring/solutions/257359/zui-xiao-fu-gai-zi-chuan-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

官方用时116ms,我357ms,是他的三倍/

一些纠缠

class Solution { public: string minWindow(string s, string t) { int ls=s.size();int lt=t.size(); if(ls<lt)return "";if(s==t)return t; vector<int> hilight; unordered_map<char,int> mp;unordered_map<char,int> mp1; for(int i =0;i<lt;i++)mp[t[i]]++; for(int i =0;i<ls;i++)if(mp[s[i]])hilight.push_back(i); int left=0;int right=0;int len=ls;int ansl,ansr;int F=0; while(left<=right&&right<hilight.size()) { for(int i=left;i<=right;i++)mp1[s[hilight[i]]]++; int flag=0; for(auto it=mp.begin();it!=mp.end();it++) if(it->second>mp1[it->first]){flag=1;right++; if(left<=right&&right<hilight.size())mp1[s[hilight[right]]]++; break;} if(!flag) { cout<<"left:"<<left<<"right:"<<right<<endl; if(len>=hilight[right]-hilight[left]+1) {F=1;len=hilight[right]-hilight[left]+1;ansl=hilight[left];ansr=hilight[right];} mp1[s[hilight[left]]]--;left++; } //mp1.clear(); }cout<<ansl<<ansr; if(F)return s.substr(ansl,ansr-ansl+1);else return ""; } };这个结果为什么不对

复制入框

ChatGLM

你的代码目的是找到字符串 s 中包含字符串 t 所有字符的最小窗口。但是代码中存在一些逻辑错误和可能的优化点。以下是对代码的分析和改进建议:

代码分析:

  1. 初始化和边界条件

    • 你正确地处理了 s 的长度小于 t 的情况和 s 等于 t 的情况。
  2. 字符频率统计

    • 你使用 mp 来统计 t 中每个字符的出现次数,这是正确的。
  3. 高亮索引

    • 你创建了一个 hilight 数组来存储 s 中所有在 t 中出现的字符的索引。这个思路是可行的,但需要注意后续处理。
  4. 滑动窗口

    • 你使用两个指针 left 和 right 来表示当前窗口的边界。但是,你的窗口调整逻辑存在一些问题。
  5. 窗口有效性检查

    • 你在每次扩展窗口后检查窗口是否包含 t 的所有字符。这个检查是必要的,但是实现方式可以优化。

代码问题:

  1. 窗口调整逻辑

    • 在扩展窗口时,你只增加了 right 指针,但没有正确地处理 left 指针的移动。
    • 当找到一个有效窗口后,你应该尝试收缩窗口(移动 left 指针),以找到更小的有效窗口。
  2. 字符频率比较

    • 你在比较 mp 和 mp1 时,如果发现窗口不包含所有字符,就只增加了 right 指针。但是,这样做可能会导致一些字符的数量超过 t 中的数量,从而影响结果的准确性。
  3. 输出和返回值

    • 你在代码中使用了 cout 来输出中间结果,这有助于调试,但最终代码中应该去掉这些输出。

改进建议:

  1. 优化窗口调整逻辑

    • 在找到一个有效窗口后,尝试收缩窗口,直到窗口不再有效为止。
  2. 精确控制字符频率

    • 确保窗口中的字符频率与 t 中的字符频率完全匹配。
  3. 去除调试输出

    • 最终代码中不应包含 cout 输出。

示例代码:

以下是改进后的代码示例:

cpp

复制

class Solution {
public:
    string minWindow(string s, string t) {
        if (s.size() < t.size()) return "";
        if (s == t) return t;

        unordered_map<char, int> need, window;
        for (char c : t) need[c]++;

        int left = 0, right = 0, valid = 0;
        int start = 0, length = INT_MAX;

        while (right < s.size()) {
            char c = s[right];
            right++;
            if (need.count(c)) {
                window[c]++;
                if (window[c] == need[c]) valid++;
            }

            while (valid == need.size()) {
                if (right - left < length) {
                    start = left;
                    length = right - left;
                }

                char d = s[left];
                left++;
                if (need.count(d)) {
                    if (window[d] == need[d]) valid--;
                    window[d]--;
                }
            }
        }

        return length == INT_MAX ? "" : s.substr(start, length);
    }
};

这个改进后的代码使用了一个更标准的滑动窗口 approach,并且确保了窗口中的字符频率与 t 中的字符频率完全匹配。同时,去除了调试输出,使代码更符合生产环境的要求。

用户_uBiEPA

Line 1122: Char 9: runtime error: reference binding to null pointer of type 'int' (stl_vector.h) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/stl_vector.h:1131:9这是什么

ChatGLM

The error message you’re seeing indicates that there is a reference binding to a null pointer in your code. This typically happens when you try to access an element of a vector that has not been initialized or has been moved from.

Let’s analyze the code snippet you provided and identify potential issues:

cpp

复制

class Solution {
public:
    string minWind

本次回答已被终止

用户_uBiEPA

中文

ChatGLM

你遇到的错误信息 “runtime error: reference binding to null pointer of type ‘int’” 指出你的代码中存在空指针引用绑定的问题。这通常发生在你尝试访问一个未初始化或已被移动的向量的元素时。

让我们分析你提供的代码片段并找出潜在的问题:

cpp

复制

class Solution 
public:
    string minWindow(string s, string t) 
    {
        int ls = s.size();
        int lt = t.size();
        if (ls < lt) return "";
        if (s == t) return t;

        vector<int> hilight;
        unordered_map<char, int> mp;
        unordered_map<char, int> mp1;
        for (int i = 0; i < lt; i++) mp[t[i]]++;
        for (int i = 0; i < ls; i++) if (mp.count(s[i])) hilight.push_back(i);
        if (hilight.empty()) return "";

        int left = 0, right = 0;
        int len = INT_MAX;
        int ansl = 0, ansr = 0;
        bool F = false;

        while (right < hilight.size()) 
        {
            mp1[s[hilight[right]]]++;
            while (check(mp, mp1)) 
            {
                if (len > hilight[right] - hilight[left] + 1) 
                {
                    len = hilight[right] - hilight[left] + 1;
                    ansl = hilight[left];
                    ansr = hilight[right];
                    F = true;
                }
                mp1[s[hilight[left]]]--;
                left++;
            }
            right++;
        }

        cout << ansl << " " << ansr << endl;
        if (F) return s.substr(ansl, ansr - ansl + 1);
        else return "";
    }

    bool check(unordered_map<char, int> mp, unordered_map<char, int> mp1) 
    {
        for (auto it : mp) 
        {
            if (mp1[it.first] < it.second) return false;
        }
        return true;
    }

问题分析:

  1. 未初始化的变量

    • int ls = s.size(); 和 int lt = t.size(); 这两行代码中,变量 ls 和 lt 的初始化是正确的,但你在后续的 for 循环中使用了未初始化的变量 i。这可能会导致未定义行为。
  2. 未定义的变量

    • 在 for (int i = 0; i < lt; i++) mp[t[i]]++; 这行代码中,i 未被正确初始化。你应该使用 int i = 0;
  3. 未定义的函数

    • check 函数未定义在类 Solution 中。你需要将其定义为 Solution 类的成员函数。
  4. 未定义的变量

    • F1 未在代码中定义和使用。

修正后的代码:

cpp

复制

#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <climits>

using namespace std;

class Solution {
public:
    string minWindow(string s, string t) 
    {
        int ls = s.size();
        int lt = t.size();
        if (ls < lt) return "";
        if (s == t) return t;

        vector<int> hilight;
        unordered_map<char, int> mp;
        unordered_map<char, int> mp1;
        for (int i = 0; i < lt; i++) mp[t[i]]++;
        for (int i = 0; i < ls; i++) if (mp.count(s[i])) hilight.push_back(i);
        if (hilight.empty()) return "";

        int left = 0, right = 0;
        int len = INT_MAX;
        int ansl = 0, ansr = 0;
        bool F = false;

        while (right < hilight.size()) 
        {
            mp1[s[hilight[right]]]++;
            while (check(mp, mp1)) 
            {
                if (len > hilight[right] - hilight[left] + 1) 
                {
                    len = hilight[right] - hilight[left] + 1;
                    ansl = hilight[left];
                    ansr = hilight[right];
                    F = true;
                }
                mp1[s[hilight[left]]]--;
                left++;
            }
            right++;
        }

        if (F) return s.substr(ansl, ansr - ansl + 1);
        else return "";
    }

    bool check(unordered_map<char, int> mp, unordered_map<char, int> mp1) 
    {
        for (auto it : mp) 
        {
            if (mp1[it.first] < it.second) return false;
        }
        return true;
    }
};

int main() {
    Solution solution;
    string s = "ADOBECODEBANC";
    string t = "ABC";
    cout << solution.minWindow(s, t) << endl;
    return 0;
}

解释:

  1. 初始化变量

    • 确保所有变量在使用前都已正确初始化。
  2. 定义 check 函数

    • 将 check 函数定义为 Solution 类的成员函数。
  3. 修复未定义的变量

    • 移除未定义的变量 F1
  4. 主函数

    • 添加一个主函数来测试 minWindow 函数。

通过这些修正,代码应该能够正确运行并找到包含字符串 t 所有字符的最小窗口。

用户_uBiEPA

c_++可以在函数里定义函数吗

ChatGLM

C++ 不允许在函数内部定义另一个函数。在C++中,函数必须定义在全局作用域、命名空间作用域或类作用域中,而不能定义在另一个函数的内部。如果你尝试在函数内部定义另一个函数,编译器将会报错。

例如,以下代码将会导致编译错误:

cpp

复制

void outerFunction() {
    void innerFunction() { // 错误:不能在函数内部定义另一个函数
        // 函数体
    }
}

如果你需要在函数内部创建类似于函数的行为,可以考虑以下替代方案:

  1. 使用lambda表达式:C++11及以后的版本支持lambda表达式,它允许你在函数内部定义匿名函数。

cpp

复制

void outerFunction() {
    auto lambda = []() {
        // Lambda函数体
    };
    lambda(); // 调用lambda表达式
}
  1. 定义函数对象:你可以创建一个类,并在该类中重载()`运算符,从而创建一个函数对象。

cpp

复制

class Functor {
public:
    void operator()() {
        // 函数体
    }
};

void outerFunction() {
    Functor functor;
    functor(); // 调用函数对象
}
  1. 将函数定义在类中:如果你在类中定义成员函数,那么这些函数将属于类的作用域,而不是另一个函数的作用域。

cpp

复制

class MyClass {
public:
    void outerFunction() {
        innerFunction(); // 调用成员函数
    }

private:
    void innerFunction() {
        // 函数体
    }
};

选择哪种替代方案取决于你的具体需求和代码风格。在现代C++中,lambda表达式通常是实现这种功能的最便捷方式。

用户_uBiEPA

int& a;int &a;int & a;int&a;还有int* a四种形式。哪些是对的

ChatGLM

在C++中,关于引用和指针的声明,你提到的几种形式中,大部分是正确的,但有一些细节需要注意。以下是每种形式的解释:

  1. int& a;
  2. int &a;
  3. int & a;
  4. int&a;
  5. int* a

解释:

  1. int& a;

    • 这是正确的。它声明了一个名为 a 的引用,该引用必须初始化为某个整数的引用。
  2. int &a;

    • 这也是正确的。在C++中,int 和 & 之间的空格是可选的,所以这种写法与第一种相同。
  3. int & a;

    • 这也是正确的。在 & 和变量名 a 之间的空格是可选的,所以这种写法与前两种相同。
  4. int&a;

    • 这也是正确的。它是一种紧凑的写法,没有空格,但仍然是有效的C++语法。
  5. int* a

    • 这是正确的。它声明了一个名为 a 的指针,该指针可以指向一个整数。

注意事项:

  • 引用必须在声明时初始化,例如:int& a = someInt;
  • 指针可以在声明时不初始化,例如:int* a;,但使用前应确保它指向一个有效的内存地址。

示例:

cpp

复制

int main() {
    int x = 10;
    int& a = x; // 正确
    int &b = x; // 正确
    int & c = x; // 正确
    int&d = x; // 正确
    int* e; // 正确,但未初始化

    // 使用引用
    a = 20;
    std::cout << x << std::endl; // 输出 20

    // 使用指针
    e = &x;
    *e = 30;
    std::cout << x << std::endl; // 输出 30

    return 0;
}

在这个示例中,所有提到的声明形式都是正确的,并且展示了如何使用引用和指针来修改变量的值。

用户_uBiEPA

int*a,int * a,int* a,int *a哪些是对的

ChatGLM

在C++中,关于指针的声明,你提到的几种形式中,大部分是正确的,但有一些细节需要注意。以下是每种形式的解释:

  1. int *a;
  2. int * a;
  3. int* a;
  4. int *a

解释:

  1. int *a;

    • 这是正确的。它声明了一个名为 a 的指针,该指针可以指向一个整数。
  2. int * a;

    • 这也是正确的。在 * 和变量名 a 之间的空格是可选的,所以这种写法与第一种相同。
  3. int* a;

    • 这也是正确的。在 int 和 * 之间的空格是可选的,所以这种写法与第一种相同。
  4. int *a

    • 这是不正确的。在 int 和 * 之间缺少空格,会导致编译器无法正确解析声明。

注意事项:

  • 在C++中,指针声明时 * 和变量名之间的空格是可选的,但类型名和 * 之间的空格是必须的。
  • 指针可以在声明时不初始化,例如:int *a;,但使用前应确保它指向一个有效的内存地址。

示例:

cpp

复制

#include <iostream>

int main() {
    int x = 10;
    int *a;        // 正确
    int * b;       // 正确
    int* c;        // 正确
    // int *d;     // 错误

    a = &x;        // 指针 a 指向 x
    *a = 20;       // 通过指针 a 修改变量 x 的值
    std::cout << x << std::endl; // 输出 20

    return 0;
}

在这个示例中,所有正确的声明形式都展示了如何使用指针来修改变量的值。注意,最后一个声明 int *d 是错误的,因为缺少了空格。

用户_uBiEPA

bool check() { for (const auto &p: ori) { if (cnt[p.first] < p.second) { return false; } } return true; } 。这边可以写成p->first吗

ChatGLM

在你提供的代码片段中,p 是通过 for 循环从 ori 中迭代出来的,其中 ori 很可能是一个 std::map 或 std::unordered_map 的实例。在这种情况下,p 是一个 std::pair<const KeyType, ValueType> 类型的对象,而不是指针。

因此,你不能使用 p->first,因为 -> 运算符是用于指针的,用于访问指针所指向对象的成员。对于非指针类型,你应该使用 . 运算符来访问成员。

所以,你的代码中的 p.first 是正确的,而 p->first 是错误的。

正确的代码应该是:

cpp

复制

bool check() {
    for (const auto &p: ori) {
        if (cnt[p.first] < p.second) {
            return false;
        }
    }
    return true;
}

如果你确实需要使用 -> 运算符,那么 p 必须是一个指向 std::pair 的指针。例如,如果 ori 是一个 std::vector<std::pair<KeyType, ValueType>*>,那么你可以这样写:

cpp

复制

bool check() {
    for (const auto *p: ori) { // 注意这里的 *p,表示 p 是一个指针
        if (cnt[p->first] < p->second) {
            return false;
        }
    }
    return true;
}

但根据你的原始代码,p 显然不是指针,所以使用 p.first 是正确的。

用户_uBiEPA

bool check() { for (const auto &p: ori) { if (cnt[p.first] < p.second) { return false; } } return true; } 。这边可以写成p->first吗,我告诉你ori是map

ChatGLM

不可以。即使 ori 是 map,你在循环中使用的 p 依然不是指针,而是一个对 pair 的引用。在 C++ 中,map 的迭代器解引用后得到的是一个 pair 对象,而不是指针。因此,你应该使用 . 运算符来访问 pair 的成员。

你的原始代码是正确的:

cpp

复制

bool check() {
    for (const auto &p: ori) {
        if (cnt[p.first] < p.second) {
            return false;
        }
    }
    return true;
}

在这段代码中,p 是一个对 pair<const KeyType, ValueType> 的引用,所以你应该使用 p.first 和 p.second 来访问 pair 的成员。

如果你坚持要使用 -> 运算符,你需要在循环中显式地获取指针,但这通常是不必要的且会使代码更复杂。例如:

cpp

复制

bool check() {
    for (const auto *p_ptr = ori.begin(); p_ptr != ori.end(); ++p_ptr) {
        if (cnt[p_ptr->first] < p_ptr->second) {
            return false;
        }
    }
    return true;
}

在这个例子中,p_ptr 是一个指向 pair<const KeyType, ValueType> 的指针,所以你可以使用 p_ptr->first 和 p_ptr->second。但是,这种写法不如你的原始代码简洁和直观。

总结:对于 map 的迭代,使用 . 运算符来访问 pair 的成员是更标准、更简洁的方式。

用户_uBiEPA

.和->在什么时候使用

ChatGLM

在C++中,.->都是用来访问对象成员的运算符,但它们的使用场景有所不同:

.运算符(点运算符):

  • 使用场景:当直接访问一个对象或对象的引用时使用。
  • 语法对象.成员 或 引用.成员
  • 示例

    cpp

    复制

    MyClass obj;
    obj.memberFunction();  // 调用对象的方法
    obj.memberVariable = 10;  // 访问对象的成员变量
    

->运算符(箭头运算符):

  • 使用场景:当通过一个指向对象的指针来访问对象的成员时使用。
  • 语法指针->成员
  • 示例

    cpp

    复制

    MyClass* ptr = new MyClass();
    ptr->memberFunction();  // 通过指针调用对象的方法
    ptr->memberVariable = 10;  // 通过指针访问对象的成员变量
    

比较:

  • 对象本身:使用.运算符。
  • 对象指针:使用->运算符。

注意事项:

  • 引用:对于引用,即使它是对象的别名,也使用.运算符,因为引用在语法上被视为对象本身。
  • 迭代器:在STL中,迭代器在某些操作上表现得像指针,但在访问成员时,通常使用.运算符,除非迭代器本身是一个指针类型。

示例:使用迭代器

cpp

复制

std::map<int, int> myMap;
for (const auto& pair : myMap) {
    // 使用.运算符,因为pair是一个引用
    std::cout << pair.first << " " << pair.second << std::endl;
}

for (auto it = myMap.begin(); it != myMap.end(); ++it) {
    // 使用->运算符,因为it是一个指针-like的迭代器
    std::cout << it->first << " " << it->second << std::endl;
}

在这个示例中,pair 是一个对 std::pair<const int, int> 的引用,所以使用.运算符。而 it 是一个迭代器,它在语法上表现得像指针,所以使用->运算符。

总之,选择.还是->取决于你是在直接操作对象还是通过指针操作对象。在大多数情况下,使用.运算符会使代码更清晰,除非你确实需要通过指针来访问成员。

用户_uBiEPA

bool check() { for (const auto &p: ori) { if (cnt[p.first] < p.second) { return false; } } return true; } const能删去吗

ChatGLM

引用

在这个特定的函数中,const 关键字用于修饰循环中的 auto 类型推导,确保 p 是一个常量引用。这表示在循环体中,p 所引用的元素不会被修改。关于是否可以删除 const,这取决于你的意图和 ori 的使用场景。

如果可以删除 const 的情况:

  1. 不修改 p:如果你在循环中确实没有修改 p,并且保证将来也不会修改 p,那么从技术上来说,const 是可以删除的。这不会影响函数的功能。

保留 const 的好处:

  1. 明确意图const 使得代码的意图更清晰,即表明你不会修改 p 所引用的元素。这有助于其他开发者理解代码,也减少了未来不小心修改 p 的风险。
  2. 兼容性:如果 ori 的类型是 const 的,例如 const std::map<Key, Value>,那么使用 const auto &p 是必要的,否则会导致编译错误。

示例:

不使用 const

cpp

复制

bool check() {
    for (auto &p: ori) {
        if (cnt[p.first] < p.second) {
            return false;
        }
    }
    return true;
}

使用 const

cpp

复制

bool check() {
    for (const auto &p: ori) {
        if (cnt[p.first] < p.second) {
            return false;
        }
    }
    return true;
}

结论:

  • 如果你想明确表示不会修改 p,并且希望代码更加健壮和易于理解,建议保留 const
  • 如果你有充分的理由相信 const 是多余的,并且确保将来不会修改 p,可以删除 const

在实际开发中,通常建议尽可能使用 const 来提供额外的安全保障和清晰度。除非有特定的性能考虑或代码风格要求,否则保留 const 是更稳妥的选择。

--c++-------------------------

在C++中,std::sort 函数用于对容器(如 std::vector)中的元素进行排序。std::sort 函数并不返回一个新的排序好的数组,而是直接在原容器上进行排序,即原地排序(in-place sorting)。

当你调用 std::sort 函数时,你传递给它的容器会被直接修改,元素会按照指定的排序准则(默认是从小到大)进行排序。如果你需要保留原始容器的顺序,你需要在排序之前复制一份容器。

下面是一个使用 std::sort 对 std::vector 进行排序的示例:

cpp

复制

#include <iostream>
#include <vector>
#include <algorithm> // for std::sort

int main() {
    std::vector<int> vec = {5, 2, 9, 1, 5, 6};

    // 对vec进行排序
    std::sort(vec.begin(), vec.end());

    // 打印排序后的vec
    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个例子中,vec 会被直接排序,而不是返回一个新的排序好的数组。排序后的结果会反映在原 vec 容器中。

如果你需要返回一个排序好的新容器而不修改原容器,你可以先复制原容器,然后对副本进行排序:

cpp

复制

#include <iostream>
#include <vector>
#include <algorithm> // for std::sort

int main() {
    std::vector<int> vec = {5, 2, 9, 1, 5, 6};
    std::vector<int> sorted_vec = vec; // 复制vec

    // 对sorted_vec进行排序
    std::sort(sorted_vec.begin(), sorted_vec.end());

    // 打印原始的vec
    std::cout << "Original vec: ";
    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 打印排序后的sorted_vec
    std::cout << "Sorted vec: ";
    for (int num : sorted_vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个例子中,sorted_vec 是 vec 的一个副本,它被排序后,原始的 vec 保持不变。

访客_693bf2

如何遍历一个map

ChatGLM

在C++中,std::map 是一个关联容器,它存储元素的方式是基于键(key)的有序集合。每个元素都有一个键和一个与之相关联的值(value)。要遍历 std::map,你可以使用多种方法。以下是几种常见的遍历 std::map 的方法:

1. 使用迭代器

迭代器是遍历容器的常用方法。std::map 提供了迭代器来遍历其元素。

cpp

复制

#include <iostream>
#include <map>

int main() {
    std::map<int, std::string> myMap;

    // 填充map
    myMap[1] = "one";
    myMap[2] = "two";
    myMap[3] = "three";

    // 使用迭代器遍历map
    for (auto it = myMap.begin(); it != myMap.end(); ++it) {
        std::cout << it->first << " => " << it->second << std::endl;
    }

    return 0;
}

2. 使用基于范围的for循环(C++11及以后)

C++11引入了基于范围的for循环,这使得遍历容器变得更加简洁。

cpp

复制

#include <iostream>
#include <map>

int main() {
    std::map<int, std::string> myMap;

    // 填充map
    myMap[1] = "one";
    myMap[2] = "two";
    myMap[3] = "three";

    // 使用基于范围的for循环遍历map
    for (const auto& pair : myMap) {
        std::cout << pair.first << " => " << pair.second << std::endl;
    }

    return 0;
}

3. 使用C++17结构化绑定(C++17及以后)

C++17引入了结构化绑定,这使得你可以直接绑定键和值。

cpp

复制

#include <iostream>
#include <map>

int main() {
    std::map<int, std::string> myMap;

    // 填充map
    myMap[1] = "one";
    myMap[2] = "two";
    myMap[3] = "three";

    // 使用结构化绑定遍历map
    for (const auto& [key, value] : myMap) {
        std::cout << key << " => " << value << std::endl;
    }

    return 0;
}

4. 使用std::for_each算法

你也可以使用 std::for_each 算法来遍历 std::map

cpp

复制

#include <iostream>
#include <map>
#include <algorithm>

int main() {
    std::map<int, std::string> myMap;

    // 填充map
    myMap[1] = "one";
    myMap[2] = "two";
    myMap[3] = "three";

    // 使用std::for_each遍历map
    std::for_each(myMap.begin(), myMap.end(), [](const std::pair<int, std::string>& pair) {
        std::cout << pair.first << " => " << pair.second << std::endl;
    });

    return 0;
}

这些方法都可以有效地遍历 std::map 中的元素。选择哪种方法取决于你的个人偏好和具体需求。

访客_693bf2

如何清空一个map

ChatGLM

引用

在C++中,清空一个std::map可以使用几种不同的方法,以下是几种常见的方式:

1. 使用clear()成员函数

clear()std::map的一个成员函数,它可以移除所有元素,使容器的大小变为0。

cpp

复制

#include <map>

int main() {
    std::map<int, std::string> myMap;

    // 填充map
    myMap[1] = "one";
    myMap[2] = "two";
    myMap[3] = "three";

    // 清空map
    myMap.clear();

    // 现在 myMap 为空
    return 0;
}

2. 使用迭代器手动删除

虽然不常用,但你也可以通过迭代器手动删除std::map中的所有元素。

cpp

复制

#include <map>

int main() {
    std::map<int, std::string> myMap;

    // 填充map
    myMap[1] = "one";
    myMap[2] = "two";
    myMap[3] = "three";

    // 使用迭代器手动删除所有元素
    for (auto it = myMap.begin(); it != myMap.end(); ) {
        it = myMap.erase(it);
    }

    // 现在 myMap 为空
    return 0;
}

3. 赋值一个空map

你可以通过赋值操作将一个空map赋给现有的map对象,这样也可以清空map。

cpp

复制

#include <map>

int main() {
    std::map<int, std::string> myMap;

    // 填充map
    myMap[1] = "one";
    myMap[2] = "two";
    myMap[3] = "three";

    // 赋值一个空map
    myMap = std::map<int, std::string>();

    // 现在 myMap 为空
    return 0;
}

4. 使用swap()方法

使用swap()方法与一个空map交换内容,也可以达到清空的目的。

cpp

复制

#include <map>

int main() {
    std::map<int, std::string> myMap;

    // 填充map
    myMap[1] = "one";
    myMap[2] = "two";
    myMap[3] = "three";

    // 使用swap与一个空map交换内容
    std::map<int, std::string>().swap(myMap);

    // 现在 myMap 为空
    return 0;
}

以上方法都可以有效地清空一个std::map。最常用和推荐的方法是使用clear()成员函数,因为它直接且清晰地表达了清空容器的意图。

未完代码存档

class Solution {
public:
        unordered_map<char,int> mp;unordered_map<char,int> mp1;

// //题解说封装
bool check()
{
for(const auto & p:mp)if(p.second>mp1[p.first])return false;
return true;
}

    string minWindow(string s, string t) {
        int ls=s.size();int lt=t.size();
        if(ls<lt)return "";if(s==t)return t;

        //vector<int> hilight;
        for(int i =0;i<lt;i++)mp[t[i]]++;
        // for(int i =0;i<ls;i++)if(mp[s[i]])hilight.push_back(i);
        // if(hilight.empty()) return "";


        int left=0;int right=0;mp1[s[0]]=1;
        int len=ls;int ansl,ansr;int F=0;
        while(left<=right&&right<ls)
        {
            // for(int i=left;i<=right;i++)mp1[s[hilight[i]]]++;
            int flag=0;
 if(check())           right++;
            if(left<=right&&right<hilight.size())mp1[s[hilight[right]]]++;
            break;}
            if(!flag)
            {
              //if(hilight[right]-lt<(hilight[left]+hilight[right])/2)
 //{
                if(len>=hilight[right]-hilight[left]+1)
            {F=1;len=hilight[right]-hilight[left]+1;ansl=hilight[left];ansr=hilight[right];cout<<"len:"<<len<<endl;}  
            mp1[s[hilight[left]]]--;left++;

                }
            }
         if(F)return s.substr(ansl,ansr-ansl+1);else return "";
           }

            //mp1.clear();

        



        
    };

 

class Solution {
public:
        unordered_map<char,int> mp;unordered_map<char,int> mp1;

// //题解说封装
bool check()
{
for(const auto & p:mp)if(p.second>mp1[p.first])return false;
return true;
}

    string minWindow(string s, string t) {
        int ls=s.size();int lt=t.size();
        if(ls<lt)return "";if(s==t)return t;

        //vector<int> hilight;
        for(int i =0;i<lt;i++)mp[t[i]]++;
        // for(int i =0;i<ls;i++)if(mp[s[i]])hilight.push_back(i);
        // if(hilight.empty()) return "";


        int left=0;int right=0;mp1[s[0]]=1;
        int len=ls;int ansl,ansr;int F=0;
        while(left<=right&&right<ls)
        {
            // for(int i=left;i<=right;i++)mp1[s[hilight[i]]]++;
            int flag=0;
            for(auto it=mp.begin();it!=mp.end();it++)
            if(it->second>mp1[it->first]){flag=1;
            right++;
            if(left<=right&&right<hilight.size())mp1[s[hilight[right]]]++;
            break;}
            if(!flag)
            {
              //if(hilight[right]-lt<(hilight[left]+hilight[right])/2)
 //{
                if(len>=hilight[right]-hilight[left]+1)
            {F=1;len=hilight[right]-hilight[left]+1;ansl=hilight[left];ansr=hilight[right];cout<<"len:"<<len<<endl;}  
            mp1[s[hilight[left]]]--;left++;

                }
            }
         if(F)return s.substr(ansl,ansr-ansl+1);else return "";
           }

            //mp1.clear();

        



        
    };

### LeetCode76题 C++ 解法 对于LeetCode76题即最小覆盖子串(Minimum Window Substring),一种有效的解决方案是采用滑动窗口技术。这种方法能够高效地找到字符串S中包含T所有字符的最小子串。 下面展示了一个具体的实现方式: ```cpp #include <unordered_map> #include <string> using namespace std; string minWindow(string s, string t) { unordered_map<char, int> need, window; for (char c : t) need[c]++; int left = 0, right = 0; int valid = 0; // 记录最小覆盖子串的起始索引及长度 int start = 0, len = INT_MAX; while (right < s.size()) { // c 是将移入窗口的字符 char c = s[right]; // 右移窗口 right++; // 进行窗口内数据的一系列更新 if (need.count(c)) { window[c]++; if (window[c] == need[c]) valid++; } // 判断左侧窗口是否要收缩 while (valid == need.size()) { // 在这里更新最小覆盖子串 if (right - left < len) { start = left; len = right - left; } // d 是将移出窗口的字符 char d = s[left]; // 左移窗口 left++; // 进行窗口内数据的一系列更新 if (need.count(d)) { if (window[d] == need[d]) valid--; window[d]--; } } } // 返回最小覆盖子串 return len == INT_MAX ? "" : s.substr(start, len); } ``` 此代码片段定义了`minWindow`函数用于寻找满足条件的最短子串[^1]。通过维护两个哈希表分别记录目标字符串`t`以及当前窗口内的字符频率,随着右指针不断向右扩展直至包含了所有的必要字符;当达到这一状态时,则尝试移动左边界以缩小范围直到不再符合条件为止,在这个过程中持续刷新最优解的信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值