第160题相交链表
题目描述:
编写一个程序,找到两个单链表相交的起始节点
这里相交可不能用值来比较,一定要使用地址来判断,因为只有地址相同的时候,才能指向同一个结点位置
解题的思路:
先算出两个链表的长度,然后让长的哪一个先走两个之间差值的步数,然后在同时走(那么他们到达相交结点的长度相同)
typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
//一定要记住不要随便的直接使用题目所给的头,要定义一个变量,然它进行一系列的操作
//这里你会发现,在有些编译器上面会报错,因为对于C语言来说,他要求你需要把变量定义在域的前面
//①求出两个链表的各自长度
ListNode* curA = headA;
int la = 0;
while(curA)
{
la++;
curA = curA->next;
}
ListNode* curB = headB;
int lb = 0;
while(curB)
{
lb++;
curB = curB->next;
}
//这里我省略了判断的过程直接假设法,我就直接设长的是curA,短的是curB
ListNode* longList = headA;
ListNode* shortList = headB;
//这里就判断一下我的假设是否正确,如果不正确那就进行修改
if(lb > la)
{
longList = headB;
shortList = headA;
}
//abs是C语言中的库函数,用来用绝对值的
int gap = abs(la-lb);
//让长的链表先走之间的差值步数
while(gap--)
{
longList = longList->next;
}
//此时之后longList和shortList是一样长的,所以随便判断哪一个都是可以的
while(longList)
{
if(longList == shortList)
{
return longList;
}
else
{
longList = longList->next;
shortList = shortList->next;
}
}
return NULL;
}
二.牛客网–链表分割
题目描述:
现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。
解题思路:带哨兵位的头结点(并不存储有效的数据)
假设原来链表为:1->6->3->2->8->9->5
假设这个x=4那么应该变成1->3->2->6->8->9->5
因为不能改变原来的顺序,现在你开辟了4个带哨兵位的头结点
注意:malloc开辟出来的空间一定要进行释放,这里的lessTail和greaterTail都里面存储着有效的数据,所以不需要释放,只需要释放两个哨兵头结点,但是在释放前你需要记住保留新排序出来的头,然后在进行释放
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
//但是你会发现提交代码之后他会给你报一个“内存超限”的错误警告,代码不能通过,这之中情况一般下就是你的循环部分
//写成了一个死循环,导致代码相当于形成了一个环
//对于原链表 1 9 3 5 6 7
// 1 3
// 9 5 6 7 这样你写的代码是没有毛病的,因为最后7的后面是NULL的(必须保证链表的最后一个所指向的下一个为空)
//但是
//对于原链表 1 9 3 5 6 7 2的时候就出现问题了
//因为cur往下来遍历,但是你的7最后又指向的2这个节点,就有问题了
typedef struct ListNode ListNode;
class Partition {
public:
ListNode* partition(ListNode* pHead, int x) {
//创建带哨兵位的头结点,里面并不存储有效的内容
ListNode* lessHead,*lessTail;
ListNode* greaterHead,*greaterTail;
//你会到最后发现lessTail和greaterTail最后就会走到有效的结点上面
lessHead = lessTail = (ListNode*)malloc(sizeof(ListNode));
greaterHead = greaterTail = (ListNode*)malloc(sizeof(ListNode));
//这里记得要对所开辟的结点进行初始化,如果你不进行初始化,那么他的下一个值是一个随机值
lessHead->next = greaterHead->next = NULL;
ListNode* cur = pHead;
while(cur)
{
if(cur->val < x)
{
lessTail->next = cur;
lessTail = lessTail->next;
}
else
{
greaterTail->next = cur;
greaterTail = greaterTail->next;
}
cur = cur->next;
}
lessTail->next = greaterHead->next;
//解决死循环的办法就是,当下面的那个都遍历完了之后就给他置空
greaterTail->next = NULL;
//一定要记住既然你是malloc出来的空间最后一定要进行释放,但是你现在里面释放掉了之后,我能怎么能找到
//这个新的排序后的头呢,所以这里要定义一个变量来保存它的头
ListNode* list = lessHead->next;
free(lessHead);
free(greaterHead);
return list;
}
};