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

203.移除链表元素  

Python

直接删除节点:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def removeElements(self, head, val):
        """
        :type head: ListNode
        :type val: int
        :rtype: ListNode
        """
        """直接删除"""
        while (head != None and head.val == val):#首先要移除头节点,确保头节点不为空,否则会报错,头节点的值==值
            head = head.next
        # 如果不是头节点,将头节点赋给指针,让指针去遍历移动
        cur = head
        while (cur != None and cur.next != None):
            if (cur.next.val == val):#注意是 值==值,not 指针
                cur.next = cur.next.next
            else:
                cur = cur.next
        return head 

            

 虚拟头节点:只用这一种即可

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def removeElements(self, head, val):
        """
        :type head: ListNode
        :type val: int
        :rtype: ListNode
        """
        """虚拟头节点"""
        dummyhead = ListNode(next = head)#创建虚拟头节点
        cur = dummyhead
        while cur.next:#写成dummyhead.next报错 因为下文一直用的是cur指针,操作空指针会报错
            if cur.next.val == val:#注意,此处是.val
                cur.next = cur.next.next
            else:
                cur = cur.next
        return dummyhead.next#要返回head,但是head可能被删除

 C++:

直接删除:

/**
 * 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) {
        //删除头节点
        while (head != NULL && head->val == val) {
            ListNode* tmp = head;//如果没有tmp,删除节点后head将指向一个已经被删除的节点
            head = head->next;
            delete tmp;
        }
        //删除非头节点
        ListNode* cur = head;
        while (cur != NULL && cur->next != NULL){
            if (cur->next->val == val){//注意是cur->next而不是cur
                ListNode* tmp = cur->next;//为什么要定义一个指针
                cur->next = cur->next->next;
                delete tmp;}
            else{
                cur = cur->next;} 
        }
        return head;
    }
};

虚拟头节点:

/**
 * 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* dummyhead = new ListNode(0);//
        dummyhead->next = head;       
        //删除节点
        ListNode* cur = dummyhead;
        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 = dummyhead->next;
        delete dummyhead;
        return head;
    }
};

707.设计链表

力扣题目链接(opens new window)

题意:

在链表类中实现这些功能:

  • get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
  • addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
  • addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
  • addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val  的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
  • deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。

 python3

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class MyLinkedList:
    def __init__(self):
        self.dummy_head = ListNode()
        self.size = 0

    def get(self, index: int) -> int:
        """ 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。"""
        # 如果index无效,则返回1,判断在范围之外
        if index < 0 or index >= self.size:#[0,size-1]
            return -1
        
        #在范围内,定义指针
        current = self.dummy_head.next #要返回当前节点的值,cur直接放到head即可
        #遍历下标内所有
        for i in range(index):
            current = current.next
        
        return current.val

    def addAtHead(self, val: int) -> None:
        """将一个值为 val 的节点插入到链表中第一个元素之前。
        在插入完成后,新节点会成为链表的第一个节点。"""
        # 直接在dummy_head后面加一个dumm_head.next即可
        self.dummy_head.next = ListNode(val, self.dummy_head.next)#直接在虚你头后面接一个节点
        self.size += 1

    def addAtTail(self, val: int) -> None:
        """ 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。"""
        # 定义指针
        current = self.dummy_head
        while current.next:#遍历,当下一个节点不是NULL,一直向下走,直到最后一个
            current = current.next
        current.next = ListNode(val)
        self.size += 1      

    def addAtIndex(self, index: int, val: int) -> None:
        """将一个值为 val 的节点插入到链表中下标为 index 的节点之前。
        如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。
        如果 index 比长度更大,该节点将 不会插入 到链表中。"""
        if index < 0 or index >= self.size:
            return
        
        current = self.dummy_head
        for i in range(index):
            current = current.next
        current.next = ListNode(val,current.next)
        self.size += 1

    def deleteAtIndex(self, index: int) -> None:
        """如果下标有效,则删除链表中下标为 index 的节点。"""
        if index < 0 or index >= self.size:
            return
        
        current = self.dummy_head
        for i in range(index):
            current = current.next
        current.next = current.next.next
        self.size -= 1 


# Your MyLinkedList object will be instantiated and called as such:
# obj = MyLinkedList()
# param_1 = obj.get(index)
# obj.addAtHead(val)
# obj.addAtTail(val)
# obj.addAtIndex(index,val)
# obj.deleteAtIndex(index)

 c++

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

    //初始化链表
    MyLinkedList() {
        _dummyHead = new LinkedNode(0);
        _size = 0;
    }
    
    //获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
    int get(int index) {
        if (index < 0 || index >(_size - 1)){
            return -1;
        }

        LinkedNode* cur = _dummyHead->next;//将指针指向要返回的head
        while (index){
            cur = cur->next;
            index--;
        }
        return cur->val;

    }
    //将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
    void addAtHead(int val) {
        LinkedNode* newNode =new LinkedNode(val);
        newNode->next = _dummyHead->next;//!!!先将原本head的值赋给插入的节点,否则就找不见了
        _dummyHead->next = newNode;
        _size++;
    }
    //将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
    void addAtTail(int val) {
        LinkedNode* newNode =new LinkedNode(val);
        LinkedNode* cur = _dummyHead;
        while (cur->next != nullptr){
            cur = cur->next;
        }
        cur->next = newNode;
        _size++;
    }
    // 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
    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;
            index--;
        }
        newNode->next = cur->next;
        cur->next = newNode;
        _size++;
    }
    //如果下标有效,则删除链表中下标为 index 的节点。
    void deleteAtIndex(int index) {
        if (index < 0 || index >=_size){//??
            return;
        }
        LinkedNode* cur = _dummyHead;
        while (index){
            cur = cur->next;
            index--;
        }
        LinkedNode* tmp = cur->next;
        cur->next = cur->next->next;
        delete tmp;;
        tmp = 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);
 */

206.反转链表 

力扣题目链接(opens new window)

题意:反转一个单链表。

示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL+

 方法一:双指针法

pyhton3

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        """双指针法"""
        cur = head
        pre = None
        while cur:
            tmp = cur.next
            cur.next = pre
            pre = cur
            cur = tmp
        return pre

C++

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

方法二:递归法

python3

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        """双指针基础上的递归法"""
        return self.reverse(head, None)

    def reverse(self, cur, pre):
        if cur == None:
            return pre
        tmp = cur.next
        cur.next = pre
        return self.reverse(tmp, cur)
    

c++

/**
 * 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) {
        return reverse(NULL, head);
        }

    ListNode* reverse(ListNode* pre,ListNode* cur){
        if (cur == NULL) return pre;
        ListNode* temp = cur->next;
        cur->next = pre;
        return reverse(cur, temp);
        }

};

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值