问题描述:
有一个字符串它的构成是词+空格的组合,如“北京 杭州 杭州 北京”, 要求输入一个匹配模式(简单的以字符来写), 比如 a a b b aabb aabb, 来判断该字符串是否符合该模式。
举例:
1. pattern = "abba", str="北京 杭州 杭州 北京" 返回 true
2. pattern = "aabb", str="北京 杭州 杭州 北京" 返回 false
3. pattern = "baab", str="北京 杭州 杭州 北京" 返回 true
解题思路:
对于 p a t t e r n pattern pattern,我们需要将其每一个字符都需要对应 s t r str str 中的一个词。
从左到右同时遍历字符数组和单词数组,并在该过程中:
当 p a t t e r n pattern pattern 字符数组第一次出现某一字符时,根据其在单词数组中的位置,记录该字符对应的单词;
当 p a t t e r n pattern pattern 字符数组第 N N N 次( N > 1 N > 1 N>1 )出现某一字符时,取出该字符应该对应的单词,并与当前字符对应在单词数组中的单词对比,如果相同则继续校验,否则返回 f a l s e false false。
如果校验至最后一个单词仍然成立,则返回 t r u e true true。
问题:如何知道字符是不是第一次出现呢? 如何记录某一字符所对应的单词呢?
代码实现:
字符串分割的函数
vector<string> split(const string &str, const string &pattern)
{
vector<string> res;
size_t start = 0, index = str.find_first_of(pattern, 0);
while (index != str.npos)
{
if (start != index)
{
res.push_back(str.substr(start, index - start));
}
start = index + 1;
index = str.find_first_of(pattern, start);
}
if (!str.substr(start).empty())
{
res.push_back(str.substr(start));
}
return res;
}
字符串匹配的函数
bool matchPattern(const string &str, const string &pattern)
{
//首先将str进行拆分
vector<string> words = split(str, " ");
//判断分割完成之后的单词长度是否等于模式的长度
if (words.size() != pattern.length())
{
return false;
}
//建立单词和拆分的单词之间的映射关系
unordered_map<char, string> map;
//从左到右同时遍历字符数组和单词数组
for (int i = 0; i < pattern.length(); ++i)
{
//如果字符是第一次出现则建立映射关系
if (map.find(pattern[i]) == map.end())
{
map.insert(make_pair(pattern[i], words[i]));
}
// 否则直接进行比较
else
{
if (map[pattern[i]] != words[i])
{
return false;
}
}
}
return true;
}
问题描述:
给定一个字符串以及多个子串,对于在字符串中出现的子串可以多次移除,求多次移除后能够得到的最短字符串长度。
输入: 第一行为一个字符串,第二行为多个子串,字符串长度大于0
输出: 多次移除后能够得到的最短字符串长度
示例1:
输入:
"ccdaabcdbb"
["ab","cd"]
输出:
2
解释:
ccdaabcdbb -> ccdacdbb -> cabb -> cb (length = 2)
示例 2:
输入:
"abcabd"
["ab","abcd"]
输出:
0
解释:
abcabd -> abcd -> "" (length = 0)
————————
解题思路:
代码实现:
int moveSubstr(string &s, unordered_set<string> &dict)
{
int size = s.size();
if (size == 0)
{
return 0;
}
queue<string> q;//存放待处理的主串
unordered_set<string> hashSet;//记录每种可能存在的主串的情况
int minLen = size;//最小的长度
q.push(s);//首先把原始主串添加进去
hashSet.insert(s);
while (!q.empty())
{
string s = q.front();//每次取队头元素作为待处理的主串
q.pop();//从队列中删除,表示该主串将要被处理
//遍历每个子串
for (auto it = dict.begin(); it != dict.end(); it++)
{
string str = *it;
//在主串中找子串,返回子串中第一个字符出现的位置
int pos = s.find(str);
while (pos != s.npos)//找到了
{
//new_s表示剔除子串之后的主串
string new_s = s.substr(0, pos) + s.substr(pos + str.size());
//没有在hashSet中找到,表示该字符串没有被处理过
if (hashSet.find(new_s) == hashSet.end())
{
q.push(new_s);//加入待处理队列
hashSet.insert(new_s);//加入hashSet中,算是一种优化
minLen = min(minLen, (int)new_s.size());//更新最小长度
// 因为可能存在同一个子串在主串中多次出现,我们必须处理该子串在主串中不同位置的情况
pos = s.find(str, pos + 1);
}
}
}
return minLen;
}
解题思路
代码实现:
long long order(long n)
{
vector<vector<long long>> dp(n + 1, vector<long long>(n + 1, 0));
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= i; ++j)
{
if (j == 1)
{
dp[i][j] = 1;//全部是并列排名
}
else
{
//有并列排名,也有独占名次的
dp[i][j] = j * (dp[i - 1][j] + dp[i - 1][j - 1]);
}
}
}
long long sum = 0;
for (int j = 1; j <= n; ++j)
{
sum += dp[n][j];//j的取值从1-n
}
return sum;
}
题目描述:
三个线程交替打印alialiali…,一个打印a,一个打印l,一个打印i
解题思路:
加互斥锁
class ali {
private:
int n;
mutex m1, m2,m3;
public:
ali(int n) {
this->n = n;
m2.lock();
m3.lock();
}
void a(function<void()> printa) {
for (int i = 0; i < n; i++) {
m1.lock();//当第一次执行时,a会被首次执行,其后a的每一次执行,都在i之后
printa();
m2.unlock();
}
}
void l(function<void()> printl) {
for (int i = 0; i < n; i++) {
m2.lock();//l的每一次执行,都在a之后
printl();
m3.unlock();
}
}
void i(function<void()> printi) {
for (int i = 0; i < n; i++) {
m3.lock();//i的每次执行,都在l之后
printi();
m1.unlock();
}
}
};
题目描述:
两个鸡蛋测试:
从100层楼往下扔鸡蛋,求最坏情况下确认保证鸡蛋可以不破的最大楼层所需次数
我们假设这个方法是存在最优解的,也就是最少的尝试次数是x次。
首先我们要想一下,那么我们第一次尝试的楼层应该是多少层。
备选答案是:x-1,x+1,x
假设第一次扔在第x+1层:
如果第一个鸡蛋碎了,那么第二个鸡蛋只能从第1层开始一层一层扔,一直扔到第x层。这样一来,我们总共尝试了x+1次,和假设尝试x次相悖。由此可见,第一次扔的楼层必须小于x+1层。
假设第一次扔在第x-1层:
如果第一个鸡蛋碎了,那么第二个鸡蛋只能从第1层开始一层一层扔,一直扔到第x-2层。这样一来,我们总共尝试了x-2+1 = x-1次,诚然,这样的数据是符合标准的,但是我们的前提是在可能的情况下,让第一枚鸡蛋发挥它最大的光和热,显然,这还不够优秀,我们再试一下最后一个备选答案。
假设第一次扔在第x层:
如果第一个鸡蛋碎了,那么第二个鸡蛋只能从第1层开始一层一层扔,一直扔到第x-1层。这样一来,我们总共尝试了x-1+1 = x次,刚刚好没有超出假设次数。
划重点了!因此,要想尽量楼层跨度大一些,又要保证不超过假设的尝试次数x,那么第一次扔鸡蛋的最优选择就是第x层。
那么下一次的鸡蛋应该扔在什么地方呢?
如果第一次的蛋蛋没有牺牲,我们的尝试次数就少了一次,同时我们也刷掉了X个错误的楼层,这时候问题就转化为了:我们有两个鸡蛋,在100-x层楼往下扔,要求尝试次数不超过x-1次。
这个时候,我们的尝试上限变成了 ( x − 1 ) (x-1) (x−1)次,由上面的尝试可以知道,这次我们的选择应该是 ( 100 − x ) (100-x) (100−x)里面的第 ( x − 1 ) (x-1) (x−1)层,即为 ( x + x − 1 ) (x+x-1) (x+x−1)层。
同理,只要是蛋蛋一直坚挺不碎的话,那么接下来就是 ( x − 2 ) (x-2) (x−2), ( x − 3 ) (x-3) (x−3)…
x + ( x − 1 ) + ( x − 2 ) + … + 1 = 100 x + (x-1) + (x-2) + … + 1 = 100 x+(x−1)+(x−2)+…+1=100
因为咱们尝试了x次呀,所以左边不就应该有x个项相加嘛,而右边就是层数100了。
(x+1)x/2 = 100 (首项+尾项)*项数/2=100
最终x向上取整,得到 x = 14
代码实现:
时间复杂度为 O ( n 2 ∗ m ) O(n^2*m) O(n2∗m)
const int N = 110, M = 11;
int n, m;
int f[N][M];
int main()
{
while (cin >> n >> m)
{
// f[i][j]表示测量区间为i,且有j个鸡蛋的测量方案
for (int i = 1; i <= n; i++) f[i][1] = i;
for (int i = 1; i <= m; i++) f[1][i] = 1;
for (int i = 2; i <= n; i++)
{
for (int j = 2; j <= m; j++)
{
//情况1:没有用过鸡蛋j,说明在测量区间长度为i时,使用了j-1个鸡蛋
f[i][j] = f[i][j - 1];
//情况2:用了鸡蛋j,需要知道在第几层用了
for (int k = 1; k <= i; k++)
{
/* 假设在k处进行了测量,又分为两种情况
* 1. 在k处鸡蛋碎了,则测量区间变为1~k-1,区间长度为k-1,鸡蛋剩余j-1个
* 2. 在k处鸡蛋没碎,测量区间为k+1~i,区间长度为i-k,鸡蛋剩余j个
* 由于我们可以控制鸡蛋在哪个位置去测,没办法控制测量的结果
* 对于我们无法控制的结果,需要取最坏的情况 max(f[k - 1][j - 1], f[i - k][j])
*/
f[i][j] = min(f[i][j], max(f[k - 1][j - 1], f[i - k][j]) + 1);
}
}
}
cout << f[n][m] << endl;
}
return 0;
}
句子中单词以空格符隔开。
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
string str;
getline(cin ,str);
reverse(str.begin(), str.end());//首先对句子整体进行翻转
vector<string> vec;
size_t pos = str.find(' ');
while (pos != std::string::npos)//将输入的字符串以空格进行分割
{
vec.push_back(str.substr(0, pos));
str = str.substr(pos+1);
pos = str.find(' ');
}
vec.push_back(str);
for (int i = 0; i < vec.size(); ++i)
{
reverse(vec[i].begin(), vec[i].end());//对单词进行翻转
}
for (string str : vec)
{
cout << str << " ";
}
}
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
bool cmp(string str1, string str2)//自定义比较规则
{
return str1 + str2 > str2 + str1;
}
int main()
{
string str;
getline(cin ,str);
vector<string> vec;
size_t pos = str.find(',');
while (pos != std::string::npos)//将输入的字符串以‘,’进行分割
{
vec.push_back(str.substr(0, pos));
str = str.substr(pos+1);
pos = str.find(',');
}
vec.push_back(str);
sort(vec.begin(), vec.end(), cmp);
for (string str : vec)
{
cout << str;
}
}
首先,我们想什么情况下会产生一个0?
一个数乘以 10,在末尾就会多出一个 0。而 10 = 5 * 2。
一组数相乘的结果末尾有几个0,取决于这组数因式分解后有几对 5 和 2 的因子。
针对于 n! 这个题目,有这样一个事实:把相乘的数因式分解后,2 的个数肯定大于 5 的个数。
所以,这个问题可以拆解为:只要求出因式分解后有几个 5 的因子即可,5的个数即是末尾出现的0的个数。
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
int count = 0;
while (n)
{
count += n / 5;
n /= 5;
}
cout << count << endl;
}
如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜。
因此我们发现了如何取胜的法则:如果n=(m+1)×r+s,(r为任意自然数,s≤m),
那么先取者要拿走s个物品,如果后取者拿走k(≤m)个,那么先取者再拿走m+1-k个,结果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜。
总之,要保持给对手留下(m+1)的倍数,就能最后获胜。
若n=k*(m+1),则后取着胜,反之,存在先取者获胜的取法。
解题思路:
后缀数组,每一行比上一行少一个,跳行就可出现少2个、3个……
abababc
bababc
ababc
babc
abc
bc
c
pair<int, string> fun(const string &str)
{
vector<string> substrs;
int len = str.length();
string substring;
int maxcount(0);
//后缀数组
cout << "the string is:" << str << endl;
cout << "the substrings are as follows:" << endl;
for (int i = 0; i < len; ++i)
{
substrs.push_back(str.substr(i));
cout << substrs[i] << endl;
}
cout << "--------------the answer------------" << endl;
for (int i = 0; i < len; ++i)
{
for (int j = i + 1; j < len; ++j)
{
int count = 1;
int sublen = j - i;
int lens = substrs[j].length();
for (int k = 0; k < lens; k += sublen)
{
if (substrs[i].substr(0,sublen) == substrs[j].substr(k,sublen))
{
++count;
}
else
{
break;
}
}
//比较最大连续出现次数,并记录相应的子串
if (count>maxcount)
{
maxcount = count;
substring = substrs[i].substr(0, sublen);
}
}
}
return make_pair(maxcount, substring);
}
int main()
{
string str = "";
auto res = fun(str);
cout << "the max count is:" << res.first << endl;
cout << "the matched substring is:" << res.second << endl;
}
题意的限定是正整数,所以可以以0为边界,只考虑0以上的数,因此结果要么在1~n之间,要么是n+1。我们的方法是以数组的下标为标准来比较。
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n,result=0;
cin >> n;
int temp,t;
vector<int> ves;
for (int i = 0; i < n; i++) {
cin >> temp;
ves.push_back(temp);
}
for (int i = n-1;i>=0; i--) {
while (0 < ves[i] && ves[i] < n&&i != ves[i]) {
t = ves[i];
if (ves[t] == ves[i]) {
break;
}
swap(ves[i], ves[t]);//归位操作
}
}
for (int i = 1; i < n; i++) {
if (ves[i] != i) {
result=i;
break;
}
}
if (result == 0) {//其他都归位了,就取决于0处的值
result=n + (ves[0] == n);
}
cout << result << endl;
return 0;
}
class Solution {
public:
int LastRemaining_Solution(int n, int m)
{
if(n<1||m<1)
{
return -1;
}
list<int> list;
for(int i=0;i<n;++i)
{
list.push_back(i);
}
auto it=list.begin();
while(list.size()>1)
{
for(int i=1;i<m;++i)//走m-1步
{
it=(++it==list.end()?list.begin():it);
}
auto del=it;//将要剔除掉的数
auto next=(++it==list.end()?list.begin():it);//保存下一个要开始报数的人
list.erase(del);
it=next;
}
return list.back();
}
};
public static int LastRemaining_Solution3(int n, int m) {
if(n == 0 || m <= 0)
return -1;
int last = 0;
for(int i = 2; i <= n; i++) {
last = (last + m) % i;
}
}
题目描述:
给定正整数N,你的任务是用最少的操作次数把1,2,3…N中所有数变为0
每次操作可从序列中选任意个整数,同时减去一个个相同的正整数。
例如:1,2,3可以同时把后两个减去2,得到1,0,1,然后再选择第一个和第三个,同时减去1即可
题目分析:
例子中,当n=3时,对数列1,2,3,把2和3同时减去2得到1,0,1,然后再选择第一个和第三个,同时减去1即可。类似的,比如当n=7时,对数列1,2,3,4,5,6,7,把4,5,6,7同时减去4得到1,2,3,0,1,2,3,此时问题等价于n=3时的情况。
令f(n)表示最少的操作次数,则有f(1)=1,f(2)=2,f(3)=2,f(4)=3,f(5)=3,f(6)=3,f(7)=3,f(8)=4,f(9)=4…通过以上规律可知,当
2 m − 1 2^{m-1} 2m−1 <=n < 2 m 2^m 2m时,f(n)=m.
代码实现:
int main()
{
int n;
cin >> n;
int sum = 0;
for (; n > 0; n /= 2)
{
sum++;
}
cout << sum;
}
题目描述
输入两个字符串s和t,判断是否可以从t中删除0个或者多个字符(顺序不变),得到字符串s,比如abcde可以得到bde,但不能得到ed。
代码实现:
bool find_string(const char *src, const char *dst)
{
while (*src)
{
if (*src == *dst)
{
dst++;
if (!(*dst))
{
return 1;
}
}
src++;
}
return 0;
}
题目描述
给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串。
举例
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"
解题思路:
哈希表记录字符串T中的值,滑动窗口法遍历字符串S寻找最小子串
如何判断s[left, right]范围的字符串包含了t中的多少个字符?
5. 在进入循环前就设置一个初值为0的count变量,用以记录s中[left, right]范围的字符串包含了t中的多少个字符。
在循环里,如果count < t.length()则说明s中[left, right]范围的字符串还没有包含t中所有字母。right指针需要向右移动。同时移动之前也要先判断是否满足right + 1 < s.length()。
接着判断s[right]是否是字符串t中的字符,每发现t中的一个字符,相应的map中的值就需要减1。
如果map中s[right]所对应字符的数量大于0,则说明t中的该字符还有剩余数量,并没有完全被s中[left, right]范围的字符串所包含,此时需要count++,同时map中对应的键的值需要-1。
如果map中s[right]所对应的字符的数量已经小于等于0了,那么说明s中[left, right]范围的字符串包含了超出t中所包含个数的相应字符,此时count不应该+1,但是map中对应的键的值仍然需要-1,表示s中[left, right]范围的字符串包含了多余的相应字符。
如果count >= t.length()则说明s中[left, right]范围的字符串已经包含了t中所有字母。left指针需要向右移动。
移动left指针之前,我们需要判断当前的left指针所指的s中的字符是否是t中的字符。
如果是,接着判断map中所对应的字符的数量是否等于0,如果等于0,则说明s中[left, right]范围的字符串所包含该字符的数量与t中所包含的数量相等,left右移缺失这个字符后,s中[left, right]范围的字符串所包含的t中的字符的数量会减少1,需要count–,同时相应的map中的值需要+1。如果map中所对应的字符的数量小于0,表示s中[left, right]范围的字符串包含了富余的相应字符,此时left右移缺失的这个字符不会导致count–,只需要map中相应的值+1即可。
代码实现:
string minWindow(string s, string t)
{
string res = "";
unordered_map<char, int> map;
for (int i = 0; i < t.length(); ++i)//保存t中字符出现的次数
{
++map[t[i]];
}
int left = 0;//滑动窗口的左边界
int right = 0;//滑动窗口的右边界
int minlen = INT_MAX;
int count = 0;
for (; right < s.length(); ++right)
{
if (--map[s[right]] >= 0)//s中包含t中的字符
{
count++;
}
while(count == t.length())//找到一个包含t中年所有字符的区间
{
if (minlen > right - left + 1)
{
minlen = right - left + 1;
res = s.substr(left, minlen);
}
if (++map[s[left]] > 0)//在s中剔除掉该字符之后会使得该区间不包含t中的该字符
{
count--;
}
++left;
}
}
}
老猴子辛苦了一辈子,给那群小猴子们留下了一笔巨大的财富——一大堆桃子。老猴子决定把这些桃子分给小猴子。
第一个猴子来了,它把桃子分成五堆,五堆一样多,但还多出一个。它把剩下的一个留给老猴子,自己拿走其中的一堆。
第二个猴子来了,它把桃子分成五堆,五堆一样多,但又多出一个。它把多出的一个留给老猴子,自己拿走其中的一堆。
后来的小猴子都如此照办。最后剩下的桃子全部留给老猴子。
这里有5只小猴子,请你写个程序计算一下在开始时至少有多少个桃子,以及最后老猴子最少能得到几个桃子。
int main()
{
int num = 1;//第5只猴子拿走的桃子数
int total = 0;//每个猴子看到的桃子数
bool checktimes = false;
while (!checktimes)
{
int count = 0;
for (int i = 5; i >= 1; i--)
{
if (i == 5) //第5只猴子看到的桃子数是以它拿走的桃子数来计算的
{
total = num * 5 + 1;
}
else
{
total = total * 5 / 4 + 1;//其他的猴子看到的桃子数都是下一个猴子看到的桃子树*5/4+1
}
if (total % 4 != 0)//从第2-5只猴子看到的桃子数应该是4的倍数
{
break;
}
else
{
count++;//如果满足条件(从第2-5只猴子看到的桃子数应该是4的倍数),就count++;
}
}
if(count==4)//说明从第2-5只猴子看到的桃子数都满足条件
{
cout << total;
checktimes = true;
}
else
{
num++;
}
}
}
题目描述
给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。
代码实现:
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n=nums.size();
for(int i=0;i<n;++i)
{
while(nums[i]>0&&nums[i]<n&&nums[i]!=nums[nums[i]-1])
{
swap(nums[i],nums[nums[i]-1]);
}
}
for(int i=0;i<n;++i)
{
if(nums[i]!=i+1)
{
return i+1;
}
}
return n+1;
}
};
int lengthOfLongestSubstring(string s)
{
int j = 0;
vector<char> vec(128);
int maxLen = INT_MIN;
for (int i = 0; i < s.size(); ++i)
{
vec[s[i]]++;
while (vec[s[i]] > 1)
{
vec[s[j]]--;
j++;
}
maxLen = max(maxLen, i - j + 1);
}
return maxLen;
}
class Solution {
public:
int minArray(vector<int>& numbers) {
int left=0;
int right=numbers.size()-1;
while(left<right)
{
int mid=(left+right)>>1;
//中间值在前半部分递增数组
if(numbers[mid]>numbers[right])
{
left=mid+1;
}
//中间值在后半部分递增数组
else if(numbers[mid]<numbers[right])
{
right=mid;
}
else
{
right--;
}
}
return numbers[left];
}
};
class Solution {
public:
int myAtoi(string str) {
int len=str.length();
int flag=1;
int i=0;
int res=0;
while(i<len)
{
while(i<len&&str[i]==' ')//去掉前导空格
{
i++;
}
if(str[i]!='+'&&str[i]!='-'&&!isdigit(str[i]))
{
return 0;
}
if(str[i]=='+'||str[i]=='-')
{
flag=str[i]=='+'?1:-1;
i++;
}
if(i<len)
{
while(i<len&&isdigit(str[i]))
{
int digit=str[i]-'0';
if(res>(INT_MAX-digit)/10)//防止溢出
{
return flag==1?INT_MAX:INT_MIN;
}
res=res*10+digit;
i++;
}
return res*flag;
}
}
return res*flag;
}
};
class MyQueue {
public:
stack<int> pushs,pops;
/** Initialize your data structure here. */
MyQueue() {
}
void fun()
{
if(pops.empty())
{
while(!pushs.empty())
{
pops.push(pushs.top());
pushs.pop();
}
}
}
/** Push element x to the back of queue. */
void push(int x) {
pushs.push(x);
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
fun();
int res=pops.top();
pops.pop();
return res;
}
/** Get the front element. */
int peek() {
fun();
return pops.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return pops.empty()&&pushs.empty();
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
class MyStack {
public:
queue<int> que;
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
que.push(x);
//将队列原来的元素重新入队
for(int i=0;i<que.size()-1;++i)
{
que.push(que.front());
que.pop();
}
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int top=que.front();
que.pop();
return top;
}
/** Get the top element. */
int top() {
return que.front();
}
/** Returns whether the stack is empty. */
bool empty() {
return que.empty();
}
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/
int Times(int n, int k, vector<int>& vec)
{
int count = 0;
int total = 0;
for (int i = 0; i < vec.size(); ++i)
{
if (vec[i] > n)
{
//cout << "不可达";
return -1;;
}
total += vec[i];
if (total > n)
{
count++;
total = 0;
i--;
}
}
return count;
}
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *reverse(ListNode *list)
{
ListNode *pre=nullptr;
while(list)
{
ListNode *next=list->next;
list->next=pre;
pre=list;
list=next;
}
return pre;
}
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode *dummy=new ListNode(-1);
dummy->next=head;
ListNode *pre=dummy;//待翻转链表的前驱节点
ListNode *end=dummy;//待翻转链表的尾节点
while(end->next)//保证至少有一个节点
{
for(int i=0;i<k&&end!=nullptr;++i)
{
end=end->next;
}
if(end==nullptr)
{
return dummy->next;
}
else
{
ListNode *next=end->next;//保存未翻转链表的头节点
end->next=nullptr;//断开
ListNode *start=pre->next;//待翻转链表的头节点
pre->next=reverse(start);//连接前边
start->next=next;//连接后边
pre=start;//更新前驱节点
end=pre;
}
}
return dummy->next;
}
};
//AaABbB
//AaABbBbb
//AaABbBbBbcbcQv
bool fun(char ch1, char ch2)
{
return (isupper(ch1) && islower(ch2)) || (islower(ch1) && isupper(ch2));
}
string deletestr(string& str)
{
vector<pair<int, int>> vec;
int len = str.length();
int i = 0;
int j = 0;
int count = -1;
while (i < len - 2)
{
if (str[i] == str[i + 2] && fun(str[i], str[i + 1]))
{
vec.push_back(make_pair(i, i + 2));
count++;
//j = i + 2;
i++;
while (i <= vec[count].second)
{
if (i + 2 <= len - 1 && str[i] == str[i + 2] && fun(str[i], str[i + 1]))
{
vec[count].second = i + 2;
}
i++;
}
i = vec[count].second + 1;
}
else
{
i++;
}
}
vector<bool> tmp(len,true);
string res;
for (int i = 0; i < vec.size(); ++i)
{
int first = vec[i].first;
int end = vec[i].second;
for (int k = first; k <= end; ++k)
{
tmp[k] = false;
}
}
for (int i = 0; i < len; ++i)
{
if (tmp[i])
{
res += str[i];
}
}
return res;
}