每日一题 | day21(洗牌 | MP3光标位置)

Posted WhiteShirtI

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一题 | day21(洗牌 | MP3光标位置)相关的知识,希望对你有一定的参考价值。

选择题

1、设一个有序的单链表中有n个结点,现要求插入一个新结点后使得单链表仍然保持有序,则该操作的时间复杂度
A O(log2n)
B O(1)
C O(n2)
D O(n)

正确答案 D:升序插入时,时间复杂度也是 O(n)

编程题

题目1
在这里插入图片描述
题解思路:
洗牌规则
在这里插入图片描述
定义两个指针,一个指针指向左手牌的第一张牌,一个指针指向右手牌的第一张牌。然后定义一个临时数组,然后将两手牌交替放进临时数组中

#include <iostream>
#include <vector>
using namespace std;

void fun1(vector<int>& vec)
{
	int sz = vec.size();
	int left = 0;
	int right = sz / 2;
	vector<int> tmp;
	while (left < sz / 2)//一次放两张,交替放牌
	{
		tmp.push_back(vec[left++]);
		tmp.push_back(vec[right++]);
	}
	vec = tmp;
}
void fun(vector<int>& vec, int k)
{
	while (k--)//洗k次牌
	{
		fun1(vec);
	}
	for (int i = 0; i < vec.size() - 1; ++i)
	{
		cout << vec[i] << " ";
	}
	cout << vec[vec.size()-1] << endl;
}

int main()
{
	int t, n, k;
	cin >> t;
	while (t--)
	{
		cin >> n >> k;
		vector<int> vec(2 * n);
		for (int i = 0; i < 2 * n; ++i)
		{
			cin >> vec[i];
		}
		fun(vec, k);
	}
	return 0;
}

题目2
在这里插入图片描述
题解思路:多读题目理解题意,根据不同状态做出不同的策略即可,代码简单,注释明了

#include <iostream>
#include <string>
#include <vector>
using namespace std;
//小于等于4首歌曲
void fun1(string& str, int n, vector<int>& vec, int& idx)
{
	vec.resize(n);
	for (int i = 0; i < n; ++i)
	{
		vec[i] = i + 1; //设置歌曲位置
	}
	for (int i = 0; i < str.size(); ++i)
	{
		if (str[i] == 'U') //光标向上移
		{
			if (idx == 1)//如果是第一页需要将光标移至最后一行
				idx = n;
			else
				--idx; //光标向上移一行
		}
		else    //光标向下移
		{
			if (idx == n) //如果是最后一页需要将光标移至第一行
				idx = 1;
			else
				++idx;//光标向下移一行
		}
	}
}
//大于4首
void fun2(string& str, int n, vector<int>& vec, int& idx)
{
	vec.resize(4);
	for (int i = 0; i < 4; ++i)
	{
		vec[i] = i + 1;//初始化第一页的歌的显示
	}
	for (int i = 0; i < str.size(); ++i)
	{
		if (str[i] == 'U')
		{
			if (idx == 1) //需要翻页到最后一页
			{
				for (int i = 0; i < 4; ++i)
				{
					vec[i] += n - 4;//页面都需要更新
				}
				idx = n;//光标移至最后一行
			}
			else 
			{
				if (idx == vec[0])//光标在一页中的第一首歌,一页一页得翻
				{
					for (int i = 0; i < 4; ++i)
					{
						--vec[i];
					}
				}
				--idx;
			}
		}
		else
		{
			if (idx == n)//需要翻页至第一页
			{
				for (int i = 0; i < 4; ++i)
				{
					vec[i] -= n - 4;
				}
				idx = 1;
			}
			else
			{
				if (idx == vec[3])//光标在一页中最后一个位置,需要一页一页得翻
				{
					for (int i = 0; i < 4; ++i)
					{
						++vec[i];
					}
				}
				++idx;
			}
		}
	}
}
void fun(string& str, int n)
{
	vector<int> res;
	int idx = 1;
	if (n <= 4)
		fun1(str, n, res, idx);
	else
		fun2(str, n, res, idx);
	for (int i = 0; i < res.size(); ++i)
	{
		cout << res[i] << " ";
	}
	cout << endl;
	cout << idx << endl;
}
int main()
{
	int n;
	while (cin >> n)
	{
		string str;
		cin >> str;
		fun(str, n);
	}
	return 0;
}

以上是关于每日一题 | day21(洗牌 | MP3光标位置)的主要内容,如果未能解决你的问题,请参考以下文章

每日一题870. 优势洗牌

力扣 每日一题 870. 优势洗牌难度:中等(贪心+双指针)

每日一题 | day09(另类加法 | 走方格的方案数)

力扣 每日一题 870. 优势洗牌难度:中等,rating: 1648(贪心+双指针)

LeetCode算法,每日一题,冲击阿里巴巴,day5

每日一题 | day13(参数解析 | 跳石板)