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

链表问题:

虚拟节点:dummy:避免讨论头结点为空。与head一样,在后面的步骤中一般不对其操作。
我的链表方向是从左到右
curNode:主要是用来遍历
nextNodecurNode的左边一个节点,是实现任务的主要变量,与preHead配合使用
preHeadcurNode的右边一个节点

LeetCode:209移除元素链表

思路:这一题还是很简单的。
关键点:分清楚几个辅助的节点的功能。

/**
 * 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) {}
 * };
 */
 //cpp
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* dummy = new ListNode(-1);
        dummy->next = head;
        ListNode* curNode = head;
        ListNode* nextNode = dummy;
        while(curNode != NULL){
            if(curNode->val == val){
                nextNode->next = curNode->next;
            }
            else{
                nextNode = nextNode->next;
            }
            curNode = curNode->next;
        }
        return dummy->next;
    }
};
//java
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode pre = dummy;
        ListNode cur = head;
        while(cur != null){
            if(cur.val == val){
                pre.next = cur.next;
            }
            else{
                pre =pre.next;
            }
            cur = cur.next;
        }
        return dummy.next;
    }
}

LeetCode:707:设计链表

几乎是看着代码随想录做完的,后面需要再刷
首先要构造出一个基本的链表节点的数据结构。

struct linkedNode{
        int val;
        linkedNode* next;
        linkedNode(int val):val(val), next(nullptr){} // 构造函数
    };
  1. 定义结构

    struct linkedNode{
    

    这是一个叫做 linkedNode 的结构体的定义。在C++中,结构体(struct)可以被用来定义一个数据结构,它可以包含多个数据成员。

  2. 数据成员

    int val;
    linkedNode *next;
    

    这个结构体有两个数据成员:

    • val:一个整数,用来存储链表节点的值。
    • next:一个指向 linkedNode 类型的指针,用来指向下一个节点。
  3. 构造函数

    linkedNode(int val):val(val), next(nullptr){}
    

    这是一个构造函数,它用于创建 linkedNode 类型的对象。

    • linkedNode(int val):这是一个带有一个整数参数的构造函数。当你创建一个 linkedNode 对象并传递一个整数时,这个构造函数会被调用。
    • :val(val), next(nullptr):这是构造函数的初始化列表。在构造函数的主体执行之前,初始化列表用于初始化数据成员。
      • val(val):这里的 val(val) 意味着将传入的参数 val 赋值给数据成员 val。注意,参数名和数据成员名是一样的,但它们是不同的变量。为了区分它们,你可以使用 this->val 来引用数据成员。
      • next(nullptr):这将 next 指针初始化为 nullptr,表示它没有指向任何节点。
    • {}:这是构造函数的主体。在这个特定的例子中,它是空的,因为所有的初始化都已经在初始化列表中完成了。

注意事项

  • 当数据成员名和构造函数参数名相同时,使用 this-> 可以帮助区分它们。但在初始化列表中,编译器可以自动区分它们,所以 this-> 不是必需的。
  • 初始化列表在构造函数主体之前执行。它是一个有效的方法来初始化数据成员,特别是当有默认值或基于其他数据成员的值时。
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)
            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* curNode = _dummyHead;
        while(curNode->next != nullptr){
            curNode = curNode->next;
        }
        curNode->next = newNode;
        _size++;
    }
    
    void addAtIndex(int index, int val) {
        if(index > _size){
            return;
        }
        if(index < 0){
            index = 0;
        }
        linkedNode* newNode = new linkedNode(val);
        linkedNode* curNode = _dummyHead;
        for(int i=0;i<index;i++){
            curNode = curNode->next;
        }
        newNode->next = curNode->next;
        curNode->next = newNode;
        _size++;
    }
    
    void deleteAtIndex(int index) {
        linkedNode* curNode = _dummyHead;
        if(index >= _size || index < 0){
            return;
        }
        while(index--){
            curNode = curNode->next;
        }
        linkedNode* temp = curNode->next;
        curNode->next = curNode->next->next;
        delete temp; // 注意在C/C++中分别要用malloc/new 对应的free/delete 来删除不用的指针,并将这款指针指向空。
        temp=nullptr;
        _size--;
    }
     void printLinkedList() {
        linkedNode* cur = _dummyHead;
        while (cur->next != nullptr) {
            cout << cur->next->val << " ";
            cur = cur->next;
        }
        cout << endl;
     }
private:
    int _size;
    linkedNode* _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);
 */
// 这道题目:要对基础的数据结构、对象的构造、
class listNode{
    int val;
    listNode next;
    listNode(){};
    listNode(int val){
        this.val = val;
    }
}
class MyLinkedList {
    int size;
    listNode head;

    public MyLinkedList() {
        // 初始化的时候不知道具体的长度size和head里面的数值,所以默认为空(0);
        size = 0;
        head =new listNode(0);
    }
    
    public int get(int index) {
        listNode cur = head;
        if(index <0||index>size-1){
            return -1;
        }
        for(int i=0;i<=index;i++){
            cur = cur.next;
        }
        return cur.val;
    }
    
    public void addAtHead(int val) {
        addAtIndex(0, val);
    }
    
    public void addAtTail(int val) {
        addAtIndex(size, val);
    }
    
    public void addAtIndex(int index, int val) {
        if(index > size){// 根据条件进行的设定
            return;
        }
        if(index < 0){  // 根据条件进行的设定
            index = 0;
        }
        size++; // 注意这里要将总长度加一
        listNode cur = head;
        for(int i=0;i<index;i++){
            cur = cur.next;
        }
        listNode insert = new listNode(val);
        insert.next = cur.next;
        cur.next = insert;
        
    }
    
    public void deleteAtIndex(int index) {
        if(index <0||index>size-1){
            return;
        }
        size--;
        if(index == 0){ 
            // 注意因为这里都是返回的head所以对于删除第一个的情况要对head单独处理,不然还是返回之前的。
            head =head.next;
            return;
        }
        listNode cur =head;
        for(int i=0;i<index;i++){
            cur = cur.next;
        }
        cur.next = cur.next.next;
    }
}

/**
 * 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);
 */

LeetCode:206:翻转链表

这是一道门槛题。
**思路:**有点类似双指针。就是要注意三个量preNode,curNode,nextNode
关键点:
curNode:主要是用来遍历
nextNodecurNode的左边一个节点,是实现任务的主要变量,与preHead配合使用
preHeadcurNode的右边一个节点.
**注意:**这里没有虚拟头结点。因为,反转之后会将虚拟头结点作为最后一个节点导致出错。直接将nextNode设置为NULL即可。

next = cur.next;
cur.next = pre;
pre = cur;
cur = next;     
lass Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* curNode = head;
        ListNode* nextNode = NULL;
        ListNode* preNode = curNode;
        while(curNode != NULL){
            preNode = curNode->next;
            curNode->next = nextNode;
            nextNode = curNode;
            curNode = preNode;
        }
        return nextNode;
    }
};
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode cur = head;
        ListNode pre = null;
        ListNode next = head;
        while(cur != null){
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
}

递归方法 (关于递归的问题后需要补充加强)

class Solution {
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode newHead = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return newHead;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值