代码随想录算法训练营第三天| 203.移除链表元素、707.设计链表、 206.反转链表

代码随想录算法训练营第三天| 203.移除链表元素、707.设计链表、 206.反转链表

  • 203.移除链表元素
  • 707.设计链表
    • 1.get(index)
    • 2.addAtHead(val)
    • 3.addAtTail(val)
    • 4.addAtIndex(index,val)
    • 5.deleteAtIndex(index)
    • 6.printLinkedList()
  • 206.反转链表

从做题到做完博客用了将近两个小时。

203.移除链表元素

题目链接:203.移除链表元素
文章讲解
状态:使用虚拟头结点可以ac,不使用会搞不清边界问题。

思路:链表的问题在脑子里回想起来觉得很简单实现,但是真正敲代码时才发现有很多边界问题,需要加以巩固。

带头结点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* Dumynode = new ListNode(0);
        Dumynode -> next = head;
        ListNode* cur = Dumynode;
        while(cur -> next != NULL)
        {
            if (cur -> next -> val == val)
            {
                ListNode* tmp = cur -> next;
                cur -> next = cur -> next -> next;
                delete tmp;
            }
            else cur = cur -> next;
        }
        head = Dumynode -> next;
        return head;
    }
};

while 循环应该保证cur的下一个不为null,因为后面要用cur -> next -> val。

不带头结点

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        while(head != NULL and head -> val == val) head = head -> next;

        ListNode* cur = head;
        while (cur != NULL and cur -> next != NULL)
        {
            if(cur -> next -> val == val)
            {
                ListNode* tmp = cur -> next;
                cur -> next = cur -> next -> next;
                delete tmp;
            }
            else cur = cur -> next;
        }
        return head;

    }
};

head != NULL是因为后面要取到head的值,cur != NULL是因为要取到cur -> next,cur -> next != NULL 是因为下面要取到cur -> next -> val,一切原因归咎于不能对空指针操作。

707.设计链表

题目链接:707.设计链表
文章讲解
状态:顺利

思路:需要注意index是从0开始的,并且index要小于等于size,大于等于0。带虚拟头结点写法。

1.get(index)

int get(int index) {
        if (index > (_size - 1) || index < 0) {
            return -1;
        }
        LinkedNode* cur = _dummyHead->next;
        while(index--){ 
            cur = cur->next;
        }
        return cur->val;
    }

2.addAtHead(val)

void addAtHead(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        newNode->next = _dummyHead->next;
        _dummyHead->next = newNode;
        _size++;

在首部添加结点时应该先把dummyhead -> next赋给newnode,然后dummyhead再指向newnode。

3.addAtTail(val)

void addAtTail(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = _dummyHead;
        while(cur->next != nullptr){
            cur = cur->next;
        }
        cur->next = newNode;
        _size++;
    }

和2.一样,这次要先把指针指向最后一个值,然后再进行2的操作。

4.addAtIndex(index,val)

void addAtIndex(int index, int val) {

        if(index > _size) return;
        if(index < 0) index = 0;        
        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = _dummyHead;
        while(index--) {
            cur = cur->next;
        }
        newNode->next = cur->next;
        cur->next = newNode;
        _size++;
    }

5.deleteAtIndex(index)

void deleteAtIndex(int index) {
        if (index >= _size || index < 0) {
            return;
        }
        LinkedNode* cur = _dummyHead;
        while(index--) {
            cur = cur ->next;
        }
        LinkedNode* tmp = cur->next;
        cur->next = cur->next->next;
        delete tmp;
      
        tmp=nullptr;
        _size--;
    }

6.printLinkedList()

void printLinkedList() {
        LinkedNode* cur = _dummyHead;
        while (cur->next != nullptr) {
            cout << cur->next->val << " ";
            cur = cur->next;
        }
        cout << endl;
    }
};

206.反转链表

题目链接:206.反转链表
文章链接
状态:顺利,递归做法有一点问题

思路:双指针做法,注意最后返回的是反转后的头结点,应该是pre,不是head。

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* tmp;
        ListNode* cur = head;
        ListNode* pre = NULL;
        
        while (cur != NULL)
        {
            tmp = cur -> next;
            cur -> next = pre;

            pre = cur;
            cur = tmp;
        }
        return pre;
    }
};

递归做法

class Solution {
public:
    ListNode* reverse(ListNode* pre,ListNode* cur)
    {
        if (cur == NULL) return pre;
        ListNode* tmp = cur -> next;
        cur -> next = pre;

        return reverse(cur,tmp);
    }

    ListNode* reverseList(ListNode* head) {
        return reverse(NULL,head);
    }
};

为什么要用return reverse呢,直接reverse为什么会错呢?

你可能感兴趣的:(算法,链表,数据结构)