LeetCode中的链表题

第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;
    }
};

猜你喜欢

转载自blog.csdn.net/MEANSWER/article/details/111872473