力扣第 267 场周赛

题目一

力扣:2076. 处理含限制条件的好友请求

在这里插入图片描述

思路:直接模拟

我们就直接模拟题意即可,我们只需要直接模拟一轮一轮买票过程,时刻检查目标人物剩余买票个数是否为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)

题目二

力扣:2074. 反转偶数长度组的节点
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路:直接模拟题意

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;
	}
};

所有代码均以通过力扣测试
(经过多次测试最短时间为):

扫描二维码关注公众号,回复: 13227198 查看本文章

在这里插入图片描述

题目三

力扣:2075. 解码斜向换位密码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路

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)

猜你喜欢

转载自blog.csdn.net/qq_45678698/article/details/121348500