题目一
思路:直接模拟
我们就直接模拟题意即可,我们只需要直接模拟一轮一轮买票过程,时刻检查目标人物剩余买票个数是否为0即可。
代码
class Solution {
public:
int timeRequiredToBuy(vector<int>& tickets, int k) {
int ans = 0;
int n = tickets.size();
while (tickets[k] != 0) {//每轮检查目标
for (int i = 0; i < n; i++) {
if (tickets[i] == 0) {
continue;
}
tickets[i]--;
ans++;
if (tickets[k] == 0) {//每次买完都要检查,因为可能在第i轮进行到某一处的时候,目标就买完了,此时就停止计数
break;
}
}
}
return ans++;
}
};
所有代码均以通过力扣测试
(经过多次测试最短时间为):
时间复杂度:O(N^2)
题目二
思路:直接模拟题意
1、一定要读好题,什么样的区间需要倒置,要看区间长度!!!1偶数长度的区间倒置,所以在策略上就得挨个枚举每个区间,用双指针法枚举每个区间,判断长度,偶数则反转。
2、在做反转的时候,切记别太死性了,要灵活,大区间的链表反转老复杂了,但是数组反转却很简单,所以转化成数组即可。(能这么做的原因之一也是因为链表本身的扩展方向没变,所以只更改数值即可)
3、思路很简单,细节满满,所以详细见代码即可。
代码
class Solution {
public:
void change(ListNode* l, ListNode* r) {
vector<int> tmp;
ListNode* p = l;
while (p != r->next) {//转化成数组
tmp.push_back(p->val);
p = p->next;
}
reverse(tmp.begin(), tmp.end());//数组反转
p = l;
int i = 0;
while (p != r->next) {//反向赋值
p->val = tmp[i++];
p = p->next;
}
}
ListNode* reverseEvenLengthGroups(ListNode* head) {
ListNode *left = nullptr, *right = nullptr;
if (head->next != nullptr) {//赋初始值
left = head->next;
if (head->next->next != nullptr) {
right = head->next->next;
}
}
int segment = 2;//第一段没意义,从第二段开始
while (left != nullptr&&right != nullptr) {
if (right == nullptr) {//防止右指针为空,仅供初始的时候即第二段服务
right = left;
}
ListNode* p = left;
int lens = 0;
while (p != right->next) {//判断该段长度
lens++;
p = p->next;
}
if (lens % 2 == 0) {//偶数长度进行翻转
change(left, right);
}
//开始移动
int step_left = segment;//左指针步长
int step_right = segment + 1;//右指针步长
for (int i = 0; i < step_left; i++) {//移动左指针
if (left != nullptr) {
left = left->next;
}
else {
break;
}
}
if (left == nullptr) {//左指针空了,则该段必定空
break;
}
for (int i = 0; i < step_right; i++) {//移动右指针
if (right != nullptr&&right->next != nullptr) {//不可以是空,所以要在空之前停下来
right = right->next;
}
else {
break;
}
}
segment += 1;//段数++
}
return head;
}
};
所有代码均以通过力扣测试
(经过多次测试最短时间为):
题目三
思路
1、思考算法的时候,一定要结合题意,样例,再辅以数据量作为辅助!!!!!!
2、先看数据量,s很大,但是换个而角度想,用O(N^2),从行列角度考虑,复杂度并不是很大。
3、读懂题,求出矩阵行列,然后把给的字符串放进矩阵,按照样例的即可,记住,我们这里分析的时候,是按照二维矩阵来的,但是事实上操作的是一维字符串s,所以有一个一维二维位置转化的过程
4、经过观察发现,从第一个开始,沿着对角线向下走,走到最后一行,然后再回到第一行,重复上述动作,一直到第一行遍历完毕即可,这就是全部过程,所以只需要模拟这个过程就行,外层循环枚举第一行所有列,然后枚举各行和该东西对应的字符即可,其实就是样例给的过程。
代码
注意:
<1> 当一行的时候,不用操作
<2> 在计算下一次的位置的时候,不能让下标越界
<3> 读题!!!!!!!!!!最后答案的末尾不能有空格,要手动处理
class Solution {
public:
string decodeCiphertext(string encodedText, int rows) {
if (rows == 1) {//特殊情况
return encodedText;
}
string ans = "";
int n = encodedText.size();
int lie = n / rows;
int fir = -1;
for (int i = 0; i < lie; i++) {//枚举列
ans += encodedText[i];
for (int j = 1; j < rows; j++) {//枚举行
int site = i + lie * j + j;//计算下一个位置在何处,这个看样例过程就能看出来
if (site < n) {
ans += encodedText[i + lie * j + j];
}
}
}
int i = ans.size() - 1;
int len = 0;//处理掉末尾的空格
for (; i >= 0; i--) {
if (ans[i] != ' ') {
break;
}
else {
len++;
}
}
ans.erase(i + 1, len);
return ans;
}
};
时间复杂度:O(N^2)