Leetcode链表专题easy总结

21.合并两个有序链表(升序)

①递归

算法思想:

思路:举例法有助于理解,假如有L1->2->5,L2->1->3,L1和L2合并成一条升序链表,比较两条链表的节点,L2的第一个节点值小,留在第一层,剩下的就是L1->2->5和L2->3合并成一条升序链表,返回值为L2第一个节点的next

递归结束条件:递归到L2的第二个节点留在上一层,此时L1->5和L2->NULL合并,再一次调用合并方法到下一层,当L2为空时,返回L1,同理可得当L1为空时,返回L2

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){

    if(list1 == NULL){
        return list2;
    }

    if(list2 == NULL){
        return list1;
    }

    if(list1->val < list2->val){
        list1->next = mergeTwoLists(list1->next,list2);
        return list1;
    }else{
        list2->next = mergeTwoLists(list2->next,list1);
        return list2;
    }
}

②哨兵节点遍历

思路:安排一个节点,next指向合并后的升序链表,再用一个指针pre指向该节点,L1与L2比较,较小的节点链接到哨兵节点后,pre再指向链接后的节点,依次迭代,直到L1或L2有一条为空,再将不为空的链表直接连接到合并后的链表后面,返回哨兵节点的next。

83.删除排序(假设升序)链表的重复元素

难点:由于是有序,重复的元素的位置是连续的

解法:遍历法

思路:定义一个遍历指针cur,判断语句为cur->next,如果cur指向的节点与下一个节点值相同,让当前所指节点指向下下个节点,如果不同,cur指向下一个节点,直到cur->next为空退出循环,返回头指针

疑问:

①为什么判断不能为cur 答:当cur指向最后一个节点时,进入判断,cur->next->val 运行出错。

②为什么只有当两个节点值不相同时,cur才会指向下一个节点 答:举例L->1->2->2->2->3

如果两个节点值相同时,cur也会向后移动一个节点,就会漏删重复的节点 

203.移除给定的链表元素

①递归

思路:画图法理解:假设删除值为3的节点

每递归一层,就留下当前节点,并将下一层递归的返回值为当前节点的next值,当递归到最后一个节点时,进入最后一层,此时head为NULL,返回head为NULL为最后一个节点的next值,此时倒数第二层的head指向最后一个节点,每一层对应一个节点

判断节点的值是否为重复的节点:将当前节点值与给定节点值比较,若相同,当前层值返回为head->next即将下一层的地址给上一层的next值,不相同,返回head给上一层的next值,回到上一层判断

②哨兵节点遍历:做法同21.②

206.反转链表

①头插法,生成一个节点做头节点,将链表中的一个个节点顺序头插到该头结点上

②遍历法:

  struct ListNode* cur = head;  struct ListNode* pre = NULL;  struct ListNode* temp;

   while(cur){

        temp = cur->next;

        cur->next = pre;

        pre = cur;

        cur = temp;    

    }

    return pre;

237.删除链表中的给定节点

解释:给定指针指向待删除的节点,链表中每个节点的值唯一

思路:删除该节点要找到其前驱节点

解法:交换该节点与后驱节点的值,删除交换后的后驱节点

234.回文链表(判断)

解法:利用快慢指针将链表一分为二,反转分割后的第二条链表,利用两个遍历指针分别遍历这两条链表,将对应节点值一 一比较,若都相同则是回文,若有不等的,则不是回文

注意:慢指针指向的节点为奇数链表节点的中间节点,偶数链表节点中间两个节点的前一个节点,在判断回文值循环中,循环条件是第二条链表不为空时。

876.链表的中间节点

详细描述:给定一个头结点为 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。

解法:

①数组移存法:将链表中指向各节点的指针存储到数组中,链表的中间节点,即为数组下标为数组长度/2的指针所指向的节点

②链表遍历法: 先遍历一次链表,确定链表的长度,再遍历链表至链表长度/2处,即为链表的中间节点

细节:第二次遍历的节点记数的count从0开始,可以看作链表像数组一样有下标标记节点并且从0开始,所以链表长度/2处为中间节点

③快慢指针法

解法:定义一个快指针、慢指针分别指向链表第一个节点,快指针每走两步,慢指针就走一步,等到快指针不能走时,慢指针所指向的节点即为中间节点

注意:快慢指针有两种写法

第一种写法:不确定head是否为空的情况下用,且链表节点为偶数时中间节点指的是第二个节点

struct ListNode* middleNode(struct ListNode* head){

    struct ListNode *slow = head;

    struct ListNode *fast = head;

    while(fast && fast->next){

        fast = fast->next->next;

        slow = slow->next;

    }

    return slow;

}

第二种写法:确定head不为空的情况下用,且链表节点为偶数时中间节点指的是第一个节点

struct ListNode* middleNode(struct ListNode* head){

    struct ListNode *slow = head;

    struct ListNode *fast = head;

    while(fast->next != NULL && fast->next->next != NULL){

        fast = fast->next->next;

        slow = slow->next;

    }

    return slow;

}

1290.二进制链表转整数

详细描述:给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。请你返回该链表所表示数字的 十进制值 。

解法:十进制、二进制相互转换原理:

①十进制转为二进制:/2 取余 逆序排列 直到商为0 余数为1为止;

②由二进制逆转为十进制: 商乘除数加余;

而链表中第一个节点的值就是最后的余数 故逆推运算的第一次的商乘除数为 0 * 2 ,最后一次取余运算的商乘除数加余获取的是上一次取余元算的商,逆转运算直至链表为空为止,即余数加完为止,最后的结果即为转化二进制前的十进制数

int getDecimalValue(struct ListNode* head){

    int ans = 0;//ans表示每一层取余运算的商,也表示最后的结果,第一次逆转运算ans初值为0

    while(head){//head不空时表示有余数,故进行逆推运算一次

        ans = ans * 2 + head->val;

        head = head->next;

    }

    return ans;

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值