算法训练第三天| 203.移除链表元素、707.设计链表、206.反转链表

链表|203.移除链表元素、707.设计链表、206.反转链表


203.移除链表元素

自己审题思路

移除链表元素,需要拿到移除元素的前一个Node地址

看完代码随想录题解后的收获

链表操作,特别是链表删除操作,建立一个虚拟节点指向头结点会很方便(否则需要考虑删除的是否是头结点)。

代码:
/*
struct ListNode {
  int val;
  ListNode*  next;
  ListNode(int val) : val(val), next(nullptr) {}
};*/
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        if (head == nullptr) return head;
        ListNode* dummyNode = new ListNode();
        dummyNode->next = head;
        ListNode* cur = dummyNode;
        while (cur->next) {
            if (cur->next->val == val) {
                cur->next = cur->next->next;
            } else {
                cur = cur->next;
            }

        }
        return dummyNode->next;
    }
};

参考详解


707.设计链表

自己审题思路

考察具体的链表操作,其中有一些细节需要注意

看完代码随想录题解后的收获

这道题覆盖了链表的常见操作,是练习链表操作非常好的一道题
其中细节比较容易犯错,借着这道题debug了一遍代码,算是为后续代码debug开个头

能够debug的代码:
// @before-stub-for-debug-begin
#include <vector>
#include <string>
#include<iostream>

using namespace std;
// @before-stub-for-debug-end

/*
 * @lc app=leetcode.cn id=707 lang=cpp
 *
 * [707] 设计链表
 */

// @lc code=start


class MyLinkedList {
public:
    struct ListNode {
        int val;
        ListNode* next;
        ListNode(int val) : val(val), next(nullptr) {}
        ListNode(int val, ListNode* next) : val(val), next(next) {}
    };

    MyLinkedList() {
        dummyNode = new ListNode(-1);
        size = 0;
    }
    
    int get(int index) {
        if (index > (size - 1) || index < 0) return -1;
        ListNode* cur = dummyNode->next;
        while(index--){
            cur = cur->next;
        }
        return cur->val;
    }
    
    /* void addAtHead(int val) {
        ListNode* newNode = new ListNode(val);
        ListNode* cur = dummyNode;
        cur->next = newNode;         //错误写法,没有将newNode->next定义,每次给链表头插入元素之后,之前添加的元素就丢失了
        size++;
    } */
    void addAtHead(int val) {
        ListNode* newNode = new ListNode(val);
        newNode->next = dummyNode->next;
        dummyNode->next = newNode;
        size++;
    }
    
    void addAtTail(int val) {
        ListNode* newNode = new ListNode(val);
        ListNode* cur = dummyNode;
        int x = size;
        while (x--) {// 之前这里使用的size--,错误,不能将size值改变!!!
            cur = cur->next;
        }
        cur->next = newNode;
        size++;
    }
    
    void addAtIndex(int index, int val) {
        if (index > size) return;
        if (index < 0) index = 0;
        ListNode* newNode = new ListNode(val);
        ListNode* cur = dummyNode;
        while (index--) {
            cur = cur->next;
        }
        ListNode* temp = cur->next;
        cur->next = newNode;
        newNode->next = temp;
/*         newNode->next = cur->next;
        cur->next = newNode; */
        size++;
    }
    
    void deleteAtIndex(int index) {
        if (index >= size || index < 0) return;
        ListNode* cur = dummyNode;
        ListNode* temp;
        while (index--) {
            cur = cur->next;
        }
        temp = cur->next;
        cur->next = cur->next->next;
        delete temp;
        temp = nullptr;
        
        size--;
    }

    void printLinkedList() {
        ListNode* cur = dummyNode;
        while (cur->next != nullptr) {
            cout << cur->next->val << " ";
            cur = cur->next;
        }
        cout << endl;
        system("pause");
    }

private:
    ListNode* dummyNode;
    int size; 
};

int main () {
    MyLinkedList* myLinkedList = new MyLinkedList();
    myLinkedList->addAtHead(1);
    myLinkedList->addAtHead(3);
    myLinkedList->addAtHead(1);
    // myLinkedList->addAtTail(3);
    myLinkedList->addAtIndex(3, 0); 
    myLinkedList->printLinkedList();
    myLinkedList->addAtIndex(1, 2);    
    myLinkedList->printLinkedList();
    myLinkedList->get(1);           
    myLinkedList->printLinkedList();
    myLinkedList->deleteAtIndex(1);  
    myLinkedList->printLinkedList();
    cout << myLinkedList->get(1) << endl;

    return 0;
}
/* int main () {
    MyLinkedList* myLinkedList = new MyLinkedList();
    myLinkedList->addAtHead(1);
    myLinkedList->addAtTail(3);
    myLinkedList->printLinkedList();
    myLinkedList->addAtIndex(1, 2);    // 链表变为 1->2->3
    myLinkedList->printLinkedList();
    myLinkedList->get(1);              // 返回 2
    myLinkedList->printLinkedList();
    myLinkedList->deleteAtIndex(1);    // 现在,链表变为 1->3
    myLinkedList->printLinkedList();
    cout << myLinkedList->get(1) << endl;              // 返回 3

    return 0;
} */

如果将ListNode* dummyNode定义在结构体struct ListNode之前,在编译时就会出现以下报错:
error: incompatible pointer types assigning to 'ListNode *' from 'MyLinkedList::ListNode *'
new ListNode(-1) 是MyLinkedList::ListNode *类型,而 dummyNode被识别成了ListNode *类型,因为在类MyLinkedList定义struct ListNode之前就定义了 dummyNode。

4070d4cf0f962addb13c89dcdedeb00.png

参考详解


206.反转链表

自己审题思路

经典题,双指针,将后一个节点指向前一个节点

看完代码随想录题解后的收获

利用双指针的思路写出递归版本代码

双指针代码:
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head == nullptr || head->next == nullptr) return head;
        ListNode* pre = nullptr;
        ListNode* cur = head;
        while(cur) {
            ListNode* tmp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = tmp;
            
        }
        return pre;
    }
};
递归版本代码:
class Solution {
public:
    ListNode* reverse(ListNode* pre, ListNode*cur) {
        if(cur == nullptr) return pre;
        ListNode* tmp = cur->next;
        cur->next = pre;
        return reverse(cur, tmp);
    }
    ListNode* reverseList(ListNode* head) {
        return reverse(nullptr, head);
    }
};

参考详解


今日感想:

1、代码隐藏的bug还是需要好好debug看看变量的变化过程;
2、还是要加强C++语法的熟悉。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容