左神算法书籍《程序员代码面试指南》——2_07将单向链表按某值划分成左边小、中间相等、右边大的形式

Problem:
【题目】 给定一个单向链表的头节点head,节点的值类型是整型,再给定一个整数pivot。
实现一个调整链表的函数,将链表调整为左部分都是值小于 pivot的节点,
中间部分都是值等于pivot的节点,右部分都是值大于 pivot的节点。
除这个要求外,对调整后的节点顺序没有更多的要求。
例如:链表9->0->4->5->1,pivot = 3。
调整后链表可以是1->0->4->9->5,
可以是0->1->9->5->4。
总之, 满足左部分都是小于3的节点,
中间部分都是等于3的节点(本例中这个部分为空),
右部分都是大于3的节点即可。对某部分内部的节点顺序不做要求。
进阶:
在原问题的要求之上再增加如下两个要求。在左、中、右三个部分的内部也做顺序要求
要求每部分里的节点从左 到右的顺序与原链表中节点的先后次序一致。
例如:链表9->0->4->5->1,pivot = 3。调整后的链表是0->1->9->4->5。
在满足原问题要求的同时,左部分节点从左到右为0、1。在原链表中也 是先出现0,后出现1;
中间部分在本例中为空,不再讨论;右部分节点 从左到右为9、4、5。在原链表中也是先出现9,然后出现4,最后出现5。

如果链表长度为N,时间复杂度请达到O(N),额外空间复杂度请达到O(1)

Solution:
使用两个指针,pr后插数来存放小数,pr前插数来存放相等的数,p为遍历游动指针

 1 #pragma once
 2
 3 #include <iostream>
 4
 5 using namespace std;
 6
 7
 8 struct Node
 9 {
10     int val;
11     Node* next;
12     Node(int a = 0) :val(a), next(NULL) {}
13 };
14
15 void Partition(Node*& head, const int num)
16 {
17     Node *pr, *p;
18     p = pr = head;
19     while (p->next)
20     {
21         if (p->next->val < num)
22         {
23             Node* q;
24             q = pr->next;
25             pr->next = p->next;
26             p->next = p->next->next;
27             pr = pr->next;
28             pr->next = q;
29         }
30         else if (p->next->val == num)
31         {
32             Node* q;
33             q = pr->next;
34             pr->next = p->next;
35             p->next = p->next->next;
36             pr->next->next = q;
37         }
38         else
39             p = p->next;
40     }
41
42 }
43
44
45 void Test()
46 {
47     int a[] = { 7,2,8,1,4,5,4,6 };
48     Node* head = new Node(-1);
49     Node* p = head;
50     for (auto n : a)
51     {
52         Node* q = new Node(n);
53         p->next = q;
54         p = q;
55     }
56     p->next = NULL;
57
58     p = head->next;
59     cout << "原链表为: ";
60     while (p)
61     {
62         cout << p->val << "->";
63         p = p->next;
64     }
65
66     Partition(head, 4);
67     p = head->next;
68     cout << endl << "*******************" << endl << "分部分后的链表为: ";
69     while (p)
70     {
71         cout << p->val << "->";
72         p = p->next;
73     }
74     cout << endl << "=============================" << endl;
75 }

原文地址:https://www.cnblogs.com/zzw1024/p/11227973.html

时间: 2024-10-12 07:50:52

左神算法书籍《程序员代码面试指南》——2_07将单向链表按某值划分成左边小、中间相等、右边大的形式的相关文章

程序员代码面试指南 IT名企算法与数据结构题目最优解 ,左程云著pdf高清版免费下载

下载地址:网盘下载 备用地址:网盘下载 内容简介  · · · · · ·这是一本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现.针对当前程序员面试缺乏权威题目汇总这一痛点,本书选取将近200道真实出现过的经典代码面试题,帮助广大程序员的面试准备做到万无一失.“刷”完本书后,你就是“题王”!__eol__本书采用题目+解答的方式组织内容,并把面试题类型相近或者解法相近的题目尽量放在一起,读者在学习本书时很容易看出面试题解法之间的联系,使知识的学习避免碎片化

左神算法书籍《程序员代码面试指南》——1_06用栈来求解汉诺塔问题

[问题] 汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间.求当塔有N层的时候,打印最优移动过程和最优移动总步数.例如,当塔数为两层时,最上层的塔记为1,最下层的塔记为2,则打印:Move 1 from left to mid Move 1 from mid to right Move 2 from left to midMove 1 from right to mid Move 1 from mid to le

左神算法书籍《程序员代码面试指南》——2_12将搜索二叉树转换成双向链表

对二叉树的节点来说,有本身的值域,有指向左孩子和右孩子的两个指针:对双向链表的节点来说,有本身的值域,有指向上一个节点和下一个节点的指针.在结构上,两种结构有相似性,现在有一棵搜索二叉树,请将其转换为一个有序的双向链表. 1 #include <iostream> 2 #include <queue> 3 using namespace std; 4 struct treeNode 5 { 6 int v; 7 treeNode *l, *r; 8 treeNode(int a =

左神算法书籍《程序员代码面试指南》——3_02打印二叉树的边界节点【★★】

[题目]给定一棵二叉树的头节点head,按照如下两种标准分别实现二叉树边界节点的逆时针打印.标准一:1.头节点为边界节点.2.叶节点为边界节点.3.如果节点在其所在的层中是最左或最右的,那么也是边界革点.标准二:1.头节点为边界节点.2.叶节点为边界节点.3.树左边界延伸下去的路径为边界节点.4.树右边界延伸下去的路径为边界节点.例如,如图3 - 2所示的树. 按标准一的打印结果为:1,2,4,7,11,13,14,15,16,12,10,6,3按标准二的打印结果为:1,2,4,7,13,14,

左神算法书籍《程序员代码面试指南》——3_08找到二叉树中符合搜索二又树条件的最大拓扑结构【***】

[题目]给定一棵二叉树的头节点head,已知所有节点的值都不一样,返回其中最大的且符合搜索二叉树条件的最大拓扑结构的大小. [题解] 方法一:二叉树的节点数为N,时间复杂度为O(N2)的方法. 首先来看这样一个问题,以节点h为头的树中,在拓扑结构中也必须以h为头的情况下,怎么找到符合搜索二叉树条件的最大结构?这个问题有一种比较容易理解的解法,我们先考查h的孩子节点,根据孩子节点的值从h开始按照二叉搜索的方式移动,如果最后能移动到同一个孩子节点上,说明这个孩子节点可以作为这个拓扑的一部分,并继续考

左神算法书籍《程序员代码面试指南》——1_01设计一个有getMin功能的栈

[题目] 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作. [要求] 1.pop.push.getMin操作的时间复杂度都是O(1).2.设计的栈类型可以使用现成的栈结构. [题解] 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作.[要求]1.pop.push.getMin操作的时间复杂度都是O(1).2.设计的栈类型可以使用现成的栈结构. 解题思路: 使用一个辅助栈,里面存的目前栈中的最小值 1 #pragma once 2 #inclu

左神算法书籍《程序员代码面试指南》——1_10最大值减去最小值小于或等于num的子数组数量

[题目]给定数组arr和整数num,共返回有多少个子数组满足如下情况:max(arr[i.j]) - min(arr[i.j]) <= num max(arfi.j])表示子数组ar[ij]中的最大值,min(arli.j])表示子数组arr[i.j]中的最小值.[要求]如果数组长度为N,请实现时间复杂度为O(N)的解法.[题解]使用两个单调栈,一个栈维持从大到小的排序,头部永远是最大值一个维持从小到大的排序,头部永远都是最小值然后使用窗口进行数据移动当右移后,最大最小差超过num时,计算这段数

左神算法书籍《程序员代码面试指南》——2_06判断一个链表是否为回文结构

[题目]给定一个链表的头节点head,请判断该链表是否为回文结构.例如:1->2->1,返回true.1->2->2->1,返回true.15->6->15,返回true.1->2->3,返回false.进阶:如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1).[题解]方法一:遍历一遍链表,将数据压入栈中然后再遍历一遍链表与栈的弹出数据对比方法二:使用快慢指针,将链表的前部分压入栈,然后栈数据弹出与链表的后半部分对比方法三:使用快慢指

[程序员代码面试指南]递归和动态规划-机器人达到指定位置方法数(一维DP待做)

题目描述 一行N个位置1到N,机器人初始位置M,机器人可以往左/右走(只能在位置范围内),规定机器人必须走K步,最终到位置P.输入这四个参数,输出机器人可以走的方法数. 解题思路 DP 方法一:时间复杂度O(NK),空间复杂度O(NK) 方法二:时间复杂度O(NK),空间复杂度O(N) 方法一代码 //ans=walk(N,M,K,P); public static int walk(int N,int cur,int rest,int P) { int[][] dp=new int[rest+