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

本文讲述了如何在LeetCode中使用C++实现链表操作,涉及移除指定值节点、自定义链表结构及反转链表的方法和代码实现。
摘要由CSDN通过智能技术生成

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

LeetCode 203.移除链表元素

题目链接:LeetCode 203.移除链表元素

Given the head of a linked list and an integer val, remove all the nodes of the linked list that has Node.val == val, and return the new head.

Example 1:

Input: head = [1,2,6,3,4,5,6], val = 6
Output: [1,2,3,4,5]

Example 2:

Input: head = [], val = 1
Output: []

添加虚拟头节点法


class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* dummyhead= new ListNode(0); 
        dummyhead->next = head;
        ListNode* cur = dummyhead;
        
        while (cur->next) {
            if (cur->next->val == val){
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            }
            else{
                cur = cur->next;
            }
        }

        head = dummyhead->next;
        delete dummyhead;

        return head;
        
    }
};

注意

  1. cur->next 删除前需要用tmp标记
  2. 删除cur->next时,需要用while将所有满足条件的删除完毕后,
    方可移动到下一个节点,否则就会漏删。

常规方法
思路:
判断是否为头节点

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        while (head && head->val==val){
            ListNode* tmp = head;
            head = head->next;
            delete tmp;
        }
        ListNode* cur = head;
        while (cur && cur->next){
            if (cur->next->val == val){
                ListNode* tmp = cur->next;
                cur->next = cur->next->next;
                delete tmp;
            }
            else{
                cur = cur->next;
            }
        }

        return head;
    }
};

注意:
1.需判断cur以及cur->next是否为空
2. 删除head时候 tmp=head,删除cur->next,tmp=cur->next.

707 设计链表

题目链接:707 设计链表

Design your implementation of the linked list. You can choose to use a singly or doubly linked list.
A node in a singly linked list should have two attributes: val and next. val is the value of the current node, and next is a pointer/reference to the next node.
If you want to use the doubly linked list, you will need one more attribute prev to indicate the previous node in the linked list. Assume all nodes in the linked list are 0-indexed.

Implement the MyLinkedList class:

MyLinkedList() Initializes the MyLinkedList object.
int get(int index) Get the value of the indexth node in the linked list. If the index is invalid, return -1.
void addAtHead(int val) Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list.
void addAtTail(int val) Append a node of value val as the last element of the linked list.
void addAtIndex(int index, int val) Add a node of value val before the indexth node in the linked list. If index equals the length of the linked list, the node will be appended to the end of the linked list. If index is greater than the length, the node will not be inserted.
void deleteAtIndex(int index) Delete the indexth node in the linked list, if the index is valid.

Example 1:

Input
["MyLinkedList", "addAtHead", "addAtTail", "addAtIndex", "get", "deleteAtIndex", "get"]
[[], [1], [3], [1, 2], [1], [1], [1]]
Output
[null, null, null, null, 2, null, 3]

Explanation
MyLinkedList myLinkedList = new MyLinkedList(); myLinkedList.addAtHead(1); myLinkedList.addAtTail(3); myLinkedList.addAtIndex(1, 2); // linked list becomes 1->2->3 myLinkedList.get(1); // return 2 myLinkedList.deleteAtIndex(1); // now the linked list is 1->3 myLinkedList.get(1); // return 3

Constraints:

0 <= index, val <= 1000
Please do not use the built-in LinkedList library.
At most 2000 calls will be made to get, addAtHead, addAtTail, addAtIndex and deleteAtIndex.

思路:

自定义数据结构

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

    MyLinkedList() {
        _dummyHead = new LinkedNode(0);
        _size = 0;
    }
    
    int get(int index) {
        if (index > (_size-1) || index < 0){
            return -1;
        }
        LinkedNode* cur = _dummyHead->next;
        while (index--){
            cur = cur->next;
        }
        return cur->val;
    }
    
    void addAtHead(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        newNode->next = _dummyHead->next;
        _dummyHead->next = newNode;
        _size ++;
    }
    
    void addAtTail(int val) {
        LinkedNode* newNode = new LinkedNode(val);
        LinkedNode* cur = _dummyHead;
        while(cur->next){
            cur = cur->next;
        }
        cur->next = newNode;
        _size ++;
    }
    
    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++;
    }
    
    void deleteAtIndex(int index) {
        if(index>(_size-1)||index<0){
            return;
        }
        LinkedNode* cur = _dummyHead;
        while (index--){
            cur = cur->next;
        }
        LinkedNode* tmp = cur->next;
        cur->next = cur->next->next;
        delete tmp;
        _size--;
    }

    private:

    LinkedNode* _dummyHead;
    int _size;

};

注意:

  1. cur 在索引时初始化为_dummyHead->next;
    在增加或删除节点时为_dummyHead;
  2. _dummyHead与Head等价;
  3. 删除或增加节点后记得变化_size大小。
  4. addAtIndex(int index, int val)的边界条件,index可以取_size
  5. 注意链表数据结构的定义;
  6. dummyHead=cur需要分析;
  7. 别忘了初始化

206 反转链表

题目链接:206 反转链表

Given the head of a singly linked list, reverse the list, and return the reversed list.

Example 1:

Input: head = [1,2,3,4,5]
Output: [5,4,3,2,1]

Example 2:

Input: head = [1,2]
Output: [2,1]
Example 3:

Input: head = []
Output: []

Constraints:

The number of nodes in the list is the range [0, 5000]. -5000 <= Node.val <= 5000

Follow up: A linked list can be reversed either iteratively or recursively. Could you implement both?

思路:

双指针法与递归法。

/**
 * 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* reverseList(ListNode* head) {
        ListNode* tmp;
        ListNode* pre = NULL;
        ListNode* cur = head;
        while (cur){
            tmp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
        
    }
};

注意:

  1. pre 和 cur两个指针,注意保存cur指针。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值