鱼C论坛

 找回密码
 立即注册
查看: 1545|回复: 13

[已解决]力扣的题76. 最小覆盖子串

[复制链接]
发表于 2021-8-10 20:23:25 | 显示全部楼层 |阅读模式
10鱼币
新写的一个想法,在评论区找不到参考,可以通过题目给的测试,但提交时的测试用例:"a""a";返回结果是"",不知道哪里错了
题目链接:https://leetcode-cn.com/problems/minimum-window-substring/
  1. class Solution {
  2. public:
  3.     string minWindow(string s, string t) {
  4.         int k=0;
  5.         int p=0,q=0;
  6.         int Minresult=s.size();
  7.         int Min=0;
  8.         string result,r;
  9.         for(int i=0;i<s.size()-t.size();i++)
  10.         {
  11.             for(int j=i;j<s.size()&&k<t.size();j++)
  12.             {
  13.                 if(t[k]==s[j])
  14.                 {
  15.                     k++;
  16.                     Min=max(Min,j);             //表示以i开头,这一段至少需要的子串
  17.                     j=i-1;
  18.                     continue;
  19.                 }                               //得到从i到Min的一串子串为需要的子串(但不一定是最小子串)
  20.             }
  21.             if(Minresult>Min-i&&(Min-i+1)>=t.size()&&k==t.size())
  22.             {
  23.                 Minresult=Min-i+1;
  24.                 p=Min;
  25.                 q=i;                            //用p,q存储最小子串的首尾位置
  26.             }
  27.             Min=0;
  28.             k=0;
  29.         }
  30.         //循环结束,返回以q开头,p结束的最小子串
  31.         if(p==0&&q==0)
  32.         {
  33.             result[0]='""';
  34.         }
  35.         else
  36.         {
  37.             for(int h=q;h<=p;h++)
  38.             {
  39.                 result.push_back(s[h]);
  40.             }
  41.         }
  42.         return result;
  43.     }
  44. };
复制代码

希望大佬们可以看看哪里错了,谢谢!
最佳答案
2021-8-10 20:23:26
这个算法不对,你现在是 j 一直后移,k 是在匹配到字符才后移,题目要求不是这样的
用这个思路写吧,虽然这个思路超时,但是至少正确
  1. 这道题的思路是:
  2. 1) begin开始指向0, end一直后移,直到begin - end区间包含T中所有字符。
  3. 记录窗口长度d
  4. 2) 然后begin开始后移移除元素,直到移除的字符是T中的字符则停止,此时T中有一个字符没被
  5. 包含在窗口,
  6. 3) 继续后移end,直到T中的所有字符被包含在窗口,重新记录最小的窗口d。
  7. 4) 如此循环知道end到S中的最后一个字符。
复制代码

  1. for(size_t j = i; j < s.size() && k < t.size(); j++)
  2. {
  3.     if(t[k] == s[j])
  4.     {
  5.         k++;

  6.         // max 赋值给 min ?
  7.         // 把最大的赋值给最小的?这是什么操作?
  8.         Min = max(Min, j);             //表示以i开头,这一段至少需要的子串
  9.         Delete(s, j);               //在这个循环中把s中已经使用过的j删除,避免无法判断重复元素   
  10.         j = i - 1;

  11.         // 为什么要加这个 continue ?
  12.         // 这里的 continue 对程序没有任何影响
  13.         // 加不加都一样
  14.         //continue;
  15.     }                               //得到从i到Min的一串子串为需要的子串(但不一定是最小子串)
  16. }
复制代码

  1. #include <iostream>
  2. #include <string>
  3. #include <algorithm>

  4. using namespace std;

  5. class Solution {
  6. public:
  7.     //void Delete(string x,int n)
  8.     void Delete(string &x,int n)
  9.     {
  10.         size_t i;
  11.         for(i=n;i<x.size()-1;i++)
  12.         {
  13.             x[i]=x[i+1];
  14.         }
  15.         x[i-1]=' ';
  16.     }

  17.     string minWindow(string s, string t) {
  18.         size_t k = 0;
  19.         int p = -1, q = -1;
  20.         size_t Minresult = s.size();
  21.         size_t Min = -1;
  22.         string result, r, S = s;
  23. #if 0
  24.         if(s.size()<t.size())
  25.         {
  26.             /*
  27.             result="";
  28.             return result;
  29.             */
  30.             return "";
  31.         }
  32.         if(s == t)
  33.         {
  34.             return s;
  35.         }
  36. #endif
  37.         if(s == t) return s;
  38.         if(s.size() < t.size()) return "";
  39.         for(size_t i = 0; i <= s.size() - t.size(); i++)
  40.         {

  41.             std::cout << "i: " << i << std::endl;

  42.             for(size_t j = i; j < s.size() && k < t.size(); j++)
  43.             {

  44.                 std::cout << "k: " << k << ", " << "t[k]: " << "'" << t[k] << "'" << std::endl;
  45.                 std::cout << "j: " << j << ", " << "s[j]: " << "'" << s[j] << "'" << std::endl;
  46.                 std::cout << std::endl;

  47.                 if(t[k] == s[j])
  48.                 {
  49.                     k++;

  50.                     // max 赋值给 min ?
  51.                     // 把最大的赋值给最小的?这是什么操作?
  52.                     Min = max(Min, j);             //表示以i开头,这一段至少需要的子串
  53.                     Delete(s, j);               //在这个循环中把s中已经使用过的j删除,避免无法判断重复元素   
  54.                     j = i - 1;

  55.                     // 为什么要加这个 continue ?
  56.                     // 这里的 continue 对程序没有任何影响
  57.                     // 加不加都一样
  58.                     //continue;
  59.                 }                               //得到从i到Min的一串子串为需要的子串(但不一定是最小子串)
  60.             }
  61.             if(Minresult > Min - i && (Min - i + 1) >= t.size() && k == t.size())
  62.             {
  63.                 Minresult = Min - i + 1;
  64.                 p = Min;
  65.                 q = i;                            //用p,q存储最小子串的首尾位置
  66.             }
  67.             Min = -1;
  68.             k = 0;
  69.             s = S;                                //还原s,开始下一次循环
  70.         }
  71.         //循环结束,返回以q开头,p结束的最小子串
  72.         if(p == -1 && q == -1) return "";
  73.         return string(&s[q], &s[p + 1]);
  74. #if 0
  75.         if(p==-1&&q==-1)
  76.         {
  77.             result="";
  78.         }
  79.         else
  80.         {
  81.             /*
  82.             for(int h=q;h<=p;h++)
  83.             {
  84.                 result.push_back(s[h]);
  85.             }
  86.             */
  87.             result = string(&s[q], &s[p + 1]);
  88.         }
  89.         return result;
  90. #endif
  91.     }
  92. };

  93. int main() {
  94.     std::cout << Solution().minWindow("bbaa", "aba") << std::endl;
  95.     return 0;
  96. }
复制代码

最佳答案

查看完整内容

这个算法不对,你现在是 j 一直后移,k 是在匹配到字符才后移,题目要求不是这样的 用这个思路写吧,虽然这个思路超时,但是至少正确
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-8-10 20:23:26 | 显示全部楼层    本楼为最佳答案   
这个算法不对,你现在是 j 一直后移,k 是在匹配到字符才后移,题目要求不是这样的
用这个思路写吧,虽然这个思路超时,但是至少正确
  1. 这道题的思路是:
  2. 1) begin开始指向0, end一直后移,直到begin - end区间包含T中所有字符。
  3. 记录窗口长度d
  4. 2) 然后begin开始后移移除元素,直到移除的字符是T中的字符则停止,此时T中有一个字符没被
  5. 包含在窗口,
  6. 3) 继续后移end,直到T中的所有字符被包含在窗口,重新记录最小的窗口d。
  7. 4) 如此循环知道end到S中的最后一个字符。
复制代码

  1. for(size_t j = i; j < s.size() && k < t.size(); j++)
  2. {
  3.     if(t[k] == s[j])
  4.     {
  5.         k++;

  6.         // max 赋值给 min ?
  7.         // 把最大的赋值给最小的?这是什么操作?
  8.         Min = max(Min, j);             //表示以i开头,这一段至少需要的子串
  9.         Delete(s, j);               //在这个循环中把s中已经使用过的j删除,避免无法判断重复元素   
  10.         j = i - 1;

  11.         // 为什么要加这个 continue ?
  12.         // 这里的 continue 对程序没有任何影响
  13.         // 加不加都一样
  14.         //continue;
  15.     }                               //得到从i到Min的一串子串为需要的子串(但不一定是最小子串)
  16. }
复制代码

  1. #include <iostream>
  2. #include <string>
  3. #include <algorithm>

  4. using namespace std;

  5. class Solution {
  6. public:
  7.     //void Delete(string x,int n)
  8.     void Delete(string &x,int n)
  9.     {
  10.         size_t i;
  11.         for(i=n;i<x.size()-1;i++)
  12.         {
  13.             x[i]=x[i+1];
  14.         }
  15.         x[i-1]=' ';
  16.     }

  17.     string minWindow(string s, string t) {
  18.         size_t k = 0;
  19.         int p = -1, q = -1;
  20.         size_t Minresult = s.size();
  21.         size_t Min = -1;
  22.         string result, r, S = s;
  23. #if 0
  24.         if(s.size()<t.size())
  25.         {
  26.             /*
  27.             result="";
  28.             return result;
  29.             */
  30.             return "";
  31.         }
  32.         if(s == t)
  33.         {
  34.             return s;
  35.         }
  36. #endif
  37.         if(s == t) return s;
  38.         if(s.size() < t.size()) return "";
  39.         for(size_t i = 0; i <= s.size() - t.size(); i++)
  40.         {

  41.             std::cout << "i: " << i << std::endl;

  42.             for(size_t j = i; j < s.size() && k < t.size(); j++)
  43.             {

  44.                 std::cout << "k: " << k << ", " << "t[k]: " << "'" << t[k] << "'" << std::endl;
  45.                 std::cout << "j: " << j << ", " << "s[j]: " << "'" << s[j] << "'" << std::endl;
  46.                 std::cout << std::endl;

  47.                 if(t[k] == s[j])
  48.                 {
  49.                     k++;

  50.                     // max 赋值给 min ?
  51.                     // 把最大的赋值给最小的?这是什么操作?
  52.                     Min = max(Min, j);             //表示以i开头,这一段至少需要的子串
  53.                     Delete(s, j);               //在这个循环中把s中已经使用过的j删除,避免无法判断重复元素   
  54.                     j = i - 1;

  55.                     // 为什么要加这个 continue ?
  56.                     // 这里的 continue 对程序没有任何影响
  57.                     // 加不加都一样
  58.                     //continue;
  59.                 }                               //得到从i到Min的一串子串为需要的子串(但不一定是最小子串)
  60.             }
  61.             if(Minresult > Min - i && (Min - i + 1) >= t.size() && k == t.size())
  62.             {
  63.                 Minresult = Min - i + 1;
  64.                 p = Min;
  65.                 q = i;                            //用p,q存储最小子串的首尾位置
  66.             }
  67.             Min = -1;
  68.             k = 0;
  69.             s = S;                                //还原s,开始下一次循环
  70.         }
  71.         //循环结束,返回以q开头,p结束的最小子串
  72.         if(p == -1 && q == -1) return "";
  73.         return string(&s[q], &s[p + 1]);
  74. #if 0
  75.         if(p==-1&&q==-1)
  76.         {
  77.             result="";
  78.         }
  79.         else
  80.         {
  81.             /*
  82.             for(int h=q;h<=p;h++)
  83.             {
  84.                 result.push_back(s[h]);
  85.             }
  86.             */
  87.             result = string(&s[q], &s[p + 1]);
  88.         }
  89.         return result;
  90. #endif
  91.     }
  92. };

  93. int main() {
  94.     std::cout << Solution().minWindow("bbaa", "aba") << std::endl;
  95.     return 0;
  96. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-8-11 00:04:00 | 显示全部楼层
for(int i=0;i<s.size()-t.size();i++)
s.size() 是 1
t.size() 是 1
1 - 1 = 0
for(int i=0;i<0;i++)
提问:这个循环执行几次?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-8-11 17:35:49 | 显示全部楼层

!哦哦哦知道了!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-8-11 18:07:37 | 显示全部楼层
本帖最后由 202021130162 于 2021-8-11 18:08 编辑


我改了一下之后又有新的问题了,如果子串里面有重复的字符,就会出错
例如:
输入:
"acbbaca"
"aba"
输出:
"bba"
预期结果:
"baca"


代码如下:
  1. class Solution {
  2. public:
  3.     void Delete(string x,int n)
  4.     {
  5.         int i;
  6.         for(i=n;i<x.size()-1;i++)
  7.         {
  8.             x[i]=x[i+1];
  9.         }
  10.         x[i-1]=' ';
  11.     }
  12.    
  13.     string minWindow(string s, string t) {
  14.         int k=0;
  15.         int p=-1,q=-1;
  16.         int Minresult=s.size();
  17.         int Min=-1;
  18.         string result,r,S=s;
  19.         if(s.size()<t.size())
  20.         {
  21.             result[0]='""';
  22.             return result;
  23.         }
  24.         if(s==t)
  25.         {
  26.             return s;
  27.         }
  28.         for(int i=0;i<=s.size()-t.size();i++)
  29.         {
  30.             for(int j=i;j<s.size()&&k<t.size();j++)
  31.             {
  32.                 if(t[k]==s[j])
  33.                 {
  34.                     k++;
  35.                     Min=max(Min,j);             //表示以i开头,这一段至少需要的子串
  36.                     Delete(s,j);               //在这个循环中把s中已经使用过的j删除,避免无法判断重复元素   
  37.                     j=i-1;
  38.                     continue;
  39.                 }                               //得到从i到Min的一串子串为需要的子串(但不一定是最小子串)
  40.             }
  41.             if(Minresult>Min-i&&(Min-i+1)>=t.size()&&k==t.size())
  42.             {
  43.                 Minresult=Min-i+1;
  44.                 p=Min;
  45.                 q=i;                            //用p,q存储最小子串的首尾位置
  46.             }
  47.             Min=-1;
  48.             k=0;
  49.             s=S;                                //还原s,开始下一次循环
  50.         }
  51.         //循环结束,返回以q开头,p结束的最小子串
  52.         if(p==-1&&q==-1)
  53.         {
  54.             result[0]='""';
  55.         }
  56.         else
  57.         {
  58.             for(int h=q;h<=p;h++)
  59.             {
  60.                 result.push_back(s[h]);
  61.             }
  62.         }
  63.         return result;
  64.     }
  65. };
复制代码


小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-8-11 18:43:09 | 显示全部楼层
202021130162 发表于 2021-8-11 18:07
我改了一下之后又有新的问题了,如果子串里面有重复的字符,就会出错
例如:
输入:
  1. #include <iostream>
  2. #include <string>

  3. using namespace std;

  4. class Solution {
  5. public:
  6.     void Delete(string x,int n)
  7.     {
  8.         int i;
  9.         for(i=n;i<x.size()-1;i++)
  10.         {
  11.             x[i]=x[i+1];
  12.         }
  13.         x[i-1]=' ';
  14.     }
  15.    
  16.     string minWindow(string s, string t) {
  17.         int k=0;
  18.         int p=-1,q=-1;
  19.         int Minresult=s.size();
  20.         int Min=-1;
  21.         string result,r,S=s;
  22.         if(s.size()<t.size())
  23.         {
  24.             result[0]='""';
  25.             return result;
  26.         }
  27.         if(s==t)
  28.         {
  29.             return s;
  30.         }
  31.         for(int i=0;i<=s.size()-t.size();i++)
  32.         {
  33.             for(int j=i;j<s.size()&&k<t.size();j++)
  34.             {
  35.                 if(t[k]==s[j])
  36.                 {
  37.                     k++;
  38.                     Min=max(Min,j);             //表示以i开头,这一段至少需要的子串
  39.                     Delete(s,j);               //在这个循环中把s中已经使用过的j删除,避免无法判断重复元素   
  40.                     j=i-1;
  41.                     continue;
  42.                 }                               //得到从i到Min的一串子串为需要的子串(但不一定是最小子串)
  43.             }
  44.             if(Minresult>Min-i&&(Min-i+1)>=t.size()&&k==t.size())
  45.             {
  46.                 Minresult=Min-i+1;
  47.                 p=Min;
  48.                 q=i;                            //用p,q存储最小子串的首尾位置
  49.             }
  50.             Min=-1;
  51.             k=0;
  52.             s=S;                                //还原s,开始下一次循环
  53.         }
  54.         //循环结束,返回以q开头,p结束的最小子串
  55.         if(p==-1&&q==-1)
  56.         {
  57.             result[0]='""';
  58.         }
  59.         else
  60.         {
  61.             for(int h=q;h<=p;h++)
  62.             {
  63.                 result.push_back(s[h]);
  64.             }
  65.         }
  66.         return result;
  67.     }
  68. };

  69. int main() {
  70.     std::cout << Solution().minWindow("acbbaca", "aba") << std::endl;
  71.     return 0;
  72. }
复制代码
  1. $ g++ -g -Wall -o main main.cpp
  2. main.cpp:26:23: warning: multi-character character constant [-Wmultichar]
  3.    26 |             result[0]='""';
  4.       |                       ^~~~
  5. main.cpp:59:23: warning: multi-character character constant [-Wmultichar]
  6.    59 |             result[0]='""';
  7.       |                       ^~~~
  8. main.cpp: In member function ‘void Solution::Delete(std::string, int)’:
  9. main.cpp:11:18: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::basic_string<char>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
  10.    11 |         for(i=n;i<x.size()-1;i++)
  11.       |                 ~^~~~~~~~~~~
  12. main.cpp: In member function ‘std::string Solution::minWindow(std::string, std::string)’:
  13. main.cpp:26:23: warning: overflow in conversion from ‘int’ to ‘std::basic_string<char>::value_type’ {aka ‘char’} changes value from ‘8738’ to ‘34’ [-Woverflow]
  14.    26 |             result[0]='""';
  15.       |                       ^~~~
  16. main.cpp:33:22: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::basic_string<char>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
  17.    33 |         for(int i=0;i<=s.size()-t.size();i++)
  18.       |                     ~^~~~~~~~~~~~~~~~~~~
  19. main.cpp:35:26: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::basic_string<char>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
  20.    35 |             for(int j=i;j<s.size()&&k<t.size();j++)
  21.       |                         ~^~~~~~~~~
  22. main.cpp:35:38: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::basic_string<char>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
  23.    35 |             for(int j=i;j<s.size()&&k<t.size();j++)
  24.       |                                     ~^~~~~~~~~
  25. main.cpp:46:42: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::basic_string<char>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
  26.    46 |             if(Minresult>Min-i&&(Min-i+1)>=t.size()&&k==t.size())
  27.       |                                 ~~~~~~~~~^~~~~~~~~~
  28. main.cpp:46:55: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::basic_string<char>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
  29.    46 |             if(Minresult>Min-i&&(Min-i+1)>=t.size()&&k==t.size())
  30.       |                                                      ~^~~~~~~~~~
  31. main.cpp:59:23: warning: overflow in conversion from ‘int’ to ‘std::basic_string<char>::value_type’ {aka ‘char’} changes value from ‘8738’ to ‘34’ [-Woverflow]
  32.    59 |             result[0]='""';
  33.       |                       ^~~~
复制代码


语法错误
result[0]='""';  // 这是什么操作?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-8-11 20:24:32 | 显示全部楼层
人造人 发表于 2021-8-11 18:43
语法错误
result[0]='""';  // 这是什么操作?

这是题目要求啊:
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

而且我在leedcode上没报错啊

                               
登录/注册后可看大图
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-8-11 22:57:47 | 显示全部楼层
202021130162 发表于 2021-8-11 20:24
这是题目要求啊:
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不 ...

你 C++ 语法不过关呀,给一个字符位置赋值一个字符串?
result[0]='""';

下面这 3 个可以
result[0] = '0';
result[0] = '\0';
result[0] = 123;

还有,有符号数和无符号数不要混用
这样就没有语法错误了,但是还有逻辑错误,这个代码无法通过测试的,我看不懂你的算法,可以说一说你的算法实现思路吗?
  1. #include <iostream>
  2. #include <string>
  3. #include <algorithm>

  4. using namespace std;

  5. class Solution {
  6. public:
  7.     void Delete(string x,int n)
  8.     {
  9.         //int i;
  10.         size_t i;
  11.         for(i=n;i<x.size()-1;i++)
  12.         {
  13.             x[i]=x[i+1];
  14.         }
  15.         x[i-1]=' ';
  16.     }

  17.     string minWindow(string s, string t) {
  18.         //int k=0;
  19.         size_t k=0;
  20.         int p=-1,q=-1;
  21.         //int Minresult=s.size();
  22.         size_t Minresult=s.size();
  23.         //int Min=-1;
  24.         size_t Min=-1;
  25.         string result,r,S=s;
  26.         if(s.size()<t.size())
  27.         {
  28.             //result[0]='""';
  29.             result="";
  30.             return result;
  31.         }
  32.         if(s==t)
  33.         {
  34.             return s;
  35.         }
  36.         //for(int i=0;i<=s.size()-t.size();i++)
  37.         for(size_t i=0;i<=s.size()-t.size();i++)
  38.         {
  39.             //for(int j=i;j<s.size()&&k<t.size();j++)
  40.             for(size_t j=i;j<s.size()&&k<t.size();j++)
  41.             {
  42.                 if(t[k]==s[j])
  43.                 {
  44.                     k++;
  45.                     Min=max(Min,j);             //表示以i开头,这一段至少需要的子串
  46.                     Delete(s,j);               //在这个循环中把s中已经使用过的j删除,避免无法判断重复元素   
  47.                     j=i-1;
  48.                     continue;
  49.                 }                               //得到从i到Min的一串子串为需要的子串(但不一定是最小子串)
  50.             }
  51.             if(Minresult>Min-i&&(Min-i+1)>=t.size()&&k==t.size())
  52.             {
  53.                 Minresult=Min-i+1;
  54.                 p=Min;
  55.                 q=i;                            //用p,q存储最小子串的首尾位置
  56.             }
  57.             Min=-1;
  58.             k=0;
  59.             s=S;                                //还原s,开始下一次循环
  60.         }
  61.         //循环结束,返回以q开头,p结束的最小子串
  62.         if(p==-1&&q==-1)
  63.         {
  64.             //result[0]='""';
  65.             result="";
  66.         }
  67.         else
  68.         {
  69.             for(int h=q;h<=p;h++)
  70.             {
  71.                 result.push_back(s[h]);
  72.             }
  73.         }
  74.         return result;
  75.     }
  76. };

  77. int main() {
  78.     std::cout << Solution().minWindow("bbaa", "aba") << std::endl;
  79.     return 0;
  80. }
复制代码



我自己也写了一个,但是算法选错了,超时
要学着调试程序呀,其实就是不断调试程序,把不通过的测试一个一个的解决
我的算法思路
这道题的思路是:
1) begin开始指向0, end一直后移,直到begin - end区间包含T中所有字符。
记录窗口长度d
2) 然后begin开始后移移除元素,直到移除的字符是T中的字符则停止,此时T中有一个字符没被
包含在窗口,
3) 继续后移end,直到T中的所有字符被包含在窗口,重新记录最小的窗口d。
4) 如此循环知道end到S中的最后一个字符。
参考: https://www.nowcoder.com/questio ... c7c9d322d12ca7955ac

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <string>

  4. using namespace std;

  5. class Solution {
  6. public:
  7.     string minWindow(string s, string t) {
  8.         size_t begin = 0, end;
  9.         string s_bak = s;
  10.         string result;
  11.         while(true) {
  12.             if(s.size() - begin < t.size()) break;
  13.             while(begin < s.size() && t.find(s[begin]) == string::npos) ++begin;
  14.             end = begin; if(begin >= s.size()) break;
  15.             for(size_t i = 0; i < t.size(); ++i) {
  16.                 size_t pos = s.find(t[i], begin);
  17.                 if(pos == string::npos) {
  18.                     end = begin; break;
  19.                 } else {
  20.                     s[pos] = -1;
  21.                     if(pos >= end) end = pos + 1;
  22.                 }
  23.             }
  24.             s = s_bak;
  25.             string new_result(&s[begin], &s[end]);
  26.             if(!new_result.empty()) {
  27.                 if(result.empty() || result.size() > new_result.size())
  28.                     result = new_result;
  29.             }
  30.             ++begin;
  31.         }
  32.         return result;
  33.     }
  34. };

  35. int main() {
  36.     std::cout << Solution().minWindow("bbaa", "aba") << std::endl;
  37.     return 0;
  38. }
复制代码


试了 19 次,最后 3 次超时,我目前对这个算法没招了,我想不到如何修改这个算法了,要通过这个测试,估计得换一个算法了,这个算法对这样的输入没办法

1.png
2.png
3.png
4.png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-8-11 22:59:30 | 显示全部楼层
202021130162 发表于 2021-8-11 20:24
这是题目要求啊:
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不 ...

leedcode 当然不报错了,它又不是用 最高级别的警告 编译代码的
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-8-11 23:40:37 | 显示全部楼层
这个函数没有如何效果
有没有调用这个函数都不会对程序有任何影响
  1.     void Delete(string x,int n)
  2.     {
  3.         int i;
  4.         for(i=n;i<x.size()-1;i++)
  5.         {
  6.             x[i]=x[i+1];
  7.         }
  8.         x[i-1]=' ';
  9.     }
复制代码



要传引用
  1.     void Delete(string &x, int n)
  2.     {
  3.         int i;
  4.         for(i=n;i<x.size()-1;i++)
  5.         {
  6.             x[i]=x[i+1];
  7.         }
  8.         x[i-1]=' ';
  9.     }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-8-12 16:03:11 | 显示全部楼层
人造人 发表于 2021-8-11 22:57
你 C++ 语法不过关呀,给一个字符位置赋值一个字符串?
result[0]='""';

我的思路:
1.对s中的每个字符s[0],s[1]...,都去查找以它开头的子串,子串中包含t中所有的字符
2.得到了许多组字符串,再从这些字符中找到长度最小的字符串,即为答案


然后对于那个Delete函数,想要实现的功能就是:
由于题目字符串t中会有重复字符,那么在查找s的子串时,我碰到一个t中的字符,就把对应的s字符删掉,这样就可以让s的子串中包含对应数量的t字符
避免出现以下情况:
输入:s=abca,t=aba
输出:ab
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-8-12 17:31:36 | 显示全部楼层
看不懂你的代码
这个代码,输入 Solution().minWindow("bbaa", "aba")
执行到 69 行的时候 p 和 q 都是 -1,也就是 58 行的 if 每一次都不成立
60,61,62 行的代码没有执行过

  1. #include <iostream>
  2. #include <string>
  3. #include <algorithm>

  4. using namespace std;

  5. class Solution {
  6. public:
  7.     //void Delete(string x,int n)
  8.     void Delete(string &x,int n)
  9.     {
  10.         size_t i;
  11.         for(i=n;i<x.size()-1;i++)
  12.         {
  13.             x[i]=x[i+1];
  14.         }
  15.         x[i-1]=' ';
  16.     }

  17.     string minWindow(string s, string t) {
  18.         size_t k=0;
  19.         int p=-1,q=-1;
  20.         size_t Minresult=s.size();
  21.         size_t Min=-1;
  22.         string result,r,S=s;
  23.         if(s.size()<t.size())
  24.         {
  25.             /*
  26.             result="";
  27.             return result;
  28.             */
  29.             return "";
  30.         }
  31.         if(s==t)
  32.         {
  33.             return s;
  34.         }
  35.         for(size_t i=0;i<=s.size()-t.size();i++)
  36.         {
  37.             for(size_t j=i;j<s.size()&&k<t.size();j++)
  38.             {
  39.                 if(t[k]==s[j])
  40.                 {
  41.                     k++;

  42.                     // max 赋值给 min ?
  43.                     // 把最大的赋值给最小的?这是什么操作?
  44.                     Min=max(Min,j);             //表示以i开头,这一段至少需要的子串
  45.                     Delete(s,j);               //在这个循环中把s中已经使用过的j删除,避免无法判断重复元素   
  46.                     j=i-1;

  47.                     // 为什么要加这个 continue ?
  48.                     // 这里的 continue 对程序没有任何影响
  49.                     // 加不加都一样
  50.                     //continue;
  51.                 }                               //得到从i到Min的一串子串为需要的子串(但不一定是最小子串)
  52.             }
  53.             if(Minresult>Min-i&&(Min-i+1)>=t.size()&&k==t.size())
  54.             {
  55.                 Minresult=Min-i+1;
  56.                 p=Min;
  57.                 q=i;                            //用p,q存储最小子串的首尾位置
  58.             }
  59.             Min=-1;
  60.             k=0;
  61.             s=S;                                //还原s,开始下一次循环
  62.         }
  63.         //循环结束,返回以q开头,p结束的最小子串
  64.         if(p==-1&&q==-1)
  65.         {
  66.             result="";
  67.         }
  68.         else
  69.         {
  70.             /*
  71.             for(int h=q;h<=p;h++)
  72.             {
  73.                 result.push_back(s[h]);
  74.             }
  75.             */
  76.             result = string(&s[q], &s[p + 1]);
  77.         }
  78.         return result;
  79.     }
  80. };

  81. int main() {
  82.     std::cout << Solution().minWindow("bbaa", "aba") << std::endl;
  83.     return 0;
  84. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-8-12 18:02:37 | 显示全部楼层
参考这个

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <string>

  4. using namespace std;

  5. class Solution {
  6. public:
  7.     string minWindow(string s, string t) {
  8.         size_t begin = 0, end;
  9.         string s_bak = s;
  10.         string result;
  11.         while(true) {
  12.             if(s.size() - begin < t.size()) break;
  13.             while(begin < s.size() && t.find(s[begin]) == string::npos) ++begin;
  14.             end = begin; if(begin >= s.size()) break;
  15.             for(size_t i = 0; i < t.size(); ++i) {
  16.                 size_t pos = s.find(t[i], begin);
  17.                 if(pos == string::npos) {
  18.                     end = begin; break;
  19.                 } else {
  20.                     s[pos] = -1;
  21.                     if(pos >= end) end = pos + 1;
  22.                 }
  23.             }
  24.             s = s_bak;
  25.             string new_result(&s[begin], &s[end]);
  26.             if(!new_result.empty()) {
  27.                 if(result.empty() || result.size() > new_result.size())
  28.                     result = new_result;
  29.             }
  30.             ++begin;
  31.         }
  32.         return result;
  33.     }
  34. };

  35. int main() {
  36.     std::cout << Solution().minWindow("bbaa", "aba") << std::endl;
  37.     return 0;
  38. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-8-14 19:15:17 | 显示全部楼层

好的,还是得用滑动窗口写,谢谢啦!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-26 21:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表