代码随想录第三天

基础知识

链表定义方式

struct ListNode {
    int val;  // 节点上存储的元素
    ListNode *next;  // 指向下一个节点的指针
    ListNode(int x) : val(x), next(NULL) {}  // 节点的构造函数
};

与数组的对比

在这里插入图片描述
摘自代码随想录

注意

给定前节点进行删除、插入操作复杂度为O(1),给定编号进行删除、插入操作复杂度为O(n)

移除链表元素

题目

https://leetcode.cn/problems/remove-linked-list-elements/

题解

问题

1.使用原链表进行删除头节点操作时,为何用while而不是if

 ListNode* removeElements(ListNode* head, int val) {
        // 删除头结点
        while (head != NULL && head->val == val) { // 注意这里不是if
            ListNode* tmp = head;
            head = head->next;
            delete tmp;
        }

笔记

1.对链表进行查找

while (cur != NULL && cur->next!= NULL){
	cur = cur->next;
}

需要先判断cur再判断cur->next,否则会出现空指针的问题。

设计链表

题目

https://leetcode.cn/problems/design-linked-list/

题解

class MyLinkedList {
public:
    struct LinkNode{
        int val;
        LinkNode* next;
        LinkNode():val(0),next(nullptr){}
        LinkNode(int x):val(x),next(nullptr){}
        LinkNode(int x,LinkNode *next):val(x),next(next){}
    };
    MyLinkedList() {
        _dummyHead = new LinkNode(0);
        _size = 0;
    }
    
    int get(int index) {
        if(index > (_size - 1)|| index < 0)
            return -1;
        int num = 0;
        LinkNode *cur = new LinkNode();
        cur = _dummyHead->next;//头节点的索引为0
        while(cur != NULL)
        {
            if(num == index)
            // if(index == 0)
                return cur->val;
            cur = cur->next;
            // index--;
            num ++;
        }
        return -1;
    }
    
    void addAtHead(int val) {
        LinkNode *newNode = new LinkNode(val);
        newNode->next = _dummyHead->next;
        _dummyHead->next = newNode;
        _size++;
        // return _dummyHead;
    }
    
    void addAtTail(int val) {
        LinkNode *newNode = new LinkNode(val);
        LinkNode *cur = new LinkNode();
        cur = _dummyHead;
        while(cur->next != NULL)
        {
            cur = cur->next;
        }
        cur->next = newNode;
        _size++;
        // return _dummyHead;

    }
    
    void addAtIndex(int index, int val) {
        // if(index > _size - 1|| index <0)
        //     return -1;
        int num = 0;
        LinkNode *newNode = new LinkNode(val);
        LinkNode *cur = new LinkNode();
        cur = _dummyHead;
        while(cur!= NULL)
        {            
            if(num == index)
            {                
                newNode->next = cur->next;
                cur->next = newNode;
                _size ++;
                break;
                // return _dummyHead;
            }
            cur = cur->next;
            num ++;
        }
    }
    
    void deleteAtIndex(int index) {
        // if(index > _size - 1|| index <0)
        //     return -1;
        int num = 0;
        LinkNode *cur = new LinkNode();
        cur = _dummyHead;
        while(cur != NULL && cur->next != NULL)
        {            
            
            if(num == index)
            {
                // cur->next = newNode;
                cur->next = cur->next->next;
                _size--;
                // return _dummyHead;
            }
            cur = cur->next;
            num ++;
        }
    }
private:
    int _size;
    LinkNode* _dummyHead;
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */

笔记

1.cur指向dummyHead->next 可以使指针直接从链表的第一个节点开始遍历,对于不同的题目可以通过极端例子进行验证,比如在查找第n个节点值时,可以使查找的节点为第0个来判断是否正确或者出现空指针的情况。
2.在查找链表的第n个节点时,不需要对cur->next!=NULL进行判断,因为这个函数只对当前节点进行操作,若加入cur->next!=NULL进行判断,可能会跳过最后一个节点
3.在尾部插入节点,终止条件要明确为最后一个节点,即cur->next == NULL
4.若要求实现在第n个节点前插入,需要保证第n个节点为cur->next,才可以对cur进行操作
5.对于遍历的cur,需要保证cur->next是题目要求的第n个节点,才可以通过对cur进行操作满足题目要求。

反转链表

题目

https://leetcode.cn/problems/reverse-linked-list/

题解

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* temp; // 保存cur的下一个节点
        ListNode* cur = head;
        ListNode* pre = NULL;
        while(cur) {
            temp = cur->next;  // 保存一下 cur的下一个节点,因为接下来要改变cur->next
            cur->next = pre; // 翻转操作
            // 更新pre 和 cur指针
            pre = cur;
            cur = temp;
        }
        return pre;
    }
};

注意:

最后一个节点应为NULL,因此pre不能用构造函数进行初始化,直接赋值为NULL。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值