C++腾讯后端实习笔试:旋转单向链表使旋转后字典序最小

旋转单向链表使字典序最小

字典序:对于两个序列a,b 若存在一个j使得对于所有的 i < j , 都有 ai= bi,且aj < bj 那么a序列的字典序小于b序列的字典序。
如输入5 2 3 4 1 那么输出 1 5 2 3 4

因为无论这个数字序列如何排列,其第一个值b1(5,2,3,4) 一定大于a1(1)。

同理输入2 2 5 2 2 输出2 2 2 2 5
输入2 2 5 2 3 输出2 2 5 2 3
输入3 4 5 1 2 输出1 2 3 4 5

笔试中给出题目的描述很多很杂,很容易读不懂题,但考察的点主要有两个:

旋转链表:

通过将单向链表连接成为循环链表完成。

调节连续的数字序列使其字典序最小

很容易想到,使数字序列中的最小值排在第一个就可以了。

但是有多个最小值呢,比如 输入 2 5 2 3 8 此时有两个最小值其后面的元素分别是3和5,那显然2 3开头的是最小字典序。则输出应该是2 3 2 5 8
也就是说,如果有多个最小值,我们去比较每个最小值后一位的值,如果后一位再相同,就再去判断后一位。

解题思路:

  1. 遍历链表找最小值
  2. 将最小值的节点的地址存入数组
  3. 比较各个最小值节点的后面的值
  4. 将链表闭合
  5. 将找到的最小值节点设为头结点,将头结点上一个节点断开

代码:

NodeList* defFirMin(NodeList* nl1, NodeList* nl2)
{
     
	NodeList* curn1 = nl1;
	NodeList* curn2 = nl2;
	// 若两个相同值的节点碰撞,说明他们的最小字典序相同
	while (curn1 != nl2)
	{
     
		if (curn1->val < curn2->val)
		{
     
			return nl1;
		}
		if (curn1->val > curn2->val)
		{
     
			return nl2;
		}
		curn1 = curn1->next;
		curn2 = curn2->next;
	}
	return nl1;//两个节点后面的值都是一样的,返回一个就可以了

}

NodeList* findMinDicOrder(NodeList* head)
{
     
	//第一次遍历,求最小值
	int minNum = head->val;
	NodeList* curNode = head;
	while (curNode->next)
	{
     
		curNode = curNode->next;
		if (minNum > curNode->val)
		{
     
			minNum = curNode->val;
		}
		
	}
	//记录尾结点
	NodeList* lastNode = curNode;
	curNode = head;
	//第二次遍历,将最小值对应的节点添加到数组
	vector<NodeList*> vList;
	while (curNode)
	{
     
		if (minNum == curNode->val)
		{
     
			vList.push_back(curNode);

		}
		curNode = curNode->next;
	}
	NodeList* minNode = vList[0];

	//多个最小值的情况,将链表首尾相接,方便处理
	lastNode->next = head;
	if (vList.size() > 1)
	{
     
		for (int i = 1; i < vList.size(); i++)
		{
     
			minNode = defFirMin(minNode, vList[i]);
		}
	}
	//此时的minNode保存使链表字典序最小的头结点
	//还原单向链表,使临时指针指向minNode的前一个节点
	curNode = minNode;
	while (curNode->next!=minNode)
	{
     
		curNode = curNode->next;
	}
	curNode->next = NULL;

	return minNode;

}

C++腾讯后端实习笔试:旋转单向链表使旋转后字典序最小_第1张图片

C++腾讯后端实习笔试:旋转单向链表使旋转后字典序最小_第2张图片
C++腾讯后端实习笔试:旋转单向链表使旋转后字典序最小_第3张图片
总结:第一次参加笔试,笔试的时候光试着去读懂题想思路就花了快一个小时,后来有思路了写出来的代码一堆bug,各种小错误。花了一个半小时做这道题,后来烦了,心灰意冷的放弃了这个题,心有不甘,写此文纪念一下,也给自己长个教训。

你可能感兴趣的:(笔试题,数据结构,算法,链表)