栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【题目】将数组和链表按某值划分成左边小,中间相等,右边大的形式(C++)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【题目】将数组和链表按某值划分成左边小,中间相等,右边大的形式(C++)

1、数组

题目没要求稳定性,利用分治算法求解

void partition(std::vector& arr, int val)
{
	if (arr.size() < 2)
	{
		return;
	}
	int left = 0, right = arr.size() - 1;
	//遍历一遍,使小于等于val在左,大于val的在右
	while (left < right)
	{
		while (left < right && arr[left] <= val)
		{
			++left;
		}

		while (left < right && arr[right] > val)
		{
			--right;
		}

		//交换left和right所在位置的数值
		swap(arr[left], arr[right]);
	}
	//此时必然left=right,并且所在位置为第一个>val的值
	//令left=0,左侧重新遍历,找到等于val的值和right交换
	left = 0;
	while (left < right)
	{
		//right指针负责寻找从右往左第一个小于val的值
		while (arr[right] >= val)
		{
			--right;
		}
		//left指针负责寻找从左往右第一个=val的值
		while (arr[left] != val)
		{
			++left;
		}

		if (left < right)
		{
			swap(arr[left], arr[right]);
		}
	}
}

复杂度分析:

时间复杂度O(N),额外空间复杂度O(1),但是不具有稳定性。

2、链表

对链表而言,比较好的解决方法是利用链表特性,将原链表按照小于val,等于val,大于val分成3个链表,再进行组合。但是如果不熟练的情况下需要多多调试

void partitionN(Node *hd, int val)
{
	Node * s_head = nullptr; //保存小于val头结点
	Node * s_end = nullptr;  //保存小于val尾结点
	Node * e_head = nullptr; //保存等于val头结点
	Node * e_end = nullptr;  //保存等于val尾结点
	Node * b_head = nullptr; //保存大于val头结点
	Node * b_end = nullptr;  //保存大于val尾结点

	//遍历一遍,将链表根据小于val,等于val,大于val拆分成3个链表
	while (nullptr != hd)
	{
		if (hd->data < val)
		{
			if (nullptr == s_head)
			{
				s_head = hd;
				s_end = hd;
			}
			else
			{
				s_end->next = hd;
				s_end = hd;
			}
		}
		else if(hd->data > val)
		{
			if (nullptr == b_head)
			{
				b_head = hd;
				b_end = hd;
			}
			else
			{
				b_end->next = hd;
				b_end = hd;
			}
		}
		else
		{
			if (nullptr == e_head)
			{
				e_head = hd;
				e_end = hd;
			}
			else
			{
				e_end->next = hd;
				e_end = hd;
			}
		}
		hd = hd->next;
	}
	//将3个链表尾的next指针置空,避免成环
	if (nullptr != s_end) s_end->next = nullptr;
	if (nullptr != e_end) e_end->next = nullptr;
	if (nullptr != b_end) b_end->next = nullptr;
	//将3个链表组合成一个链表返回
	if (nullptr != s_head)
	{
		hd = s_head;
		s_end->next = b_head;
	}
	
	if(nullptr != e_head)
	{
		if (nullptr == hd)
		{
			hd = e_head;
		}
		else
		{
			s_end->next = e_head;
		}

		e_end->next = b_head;
	}

	if (nullptr == hd)
	{
		hd = b_head;
	}
}

复杂度分析:

时间复杂度O(N),额外空间复杂度O(1),且具有稳定性。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/996053.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号