算法60天训练–9-8-day3

算法60天训练–9-8-day3


(画图有些不规范)

203. 移除链表元素

思路

首先删除一个链表元素,无非就是将要删除的链表结点的上一个结点指向这个被删除链表的下一个结点

image-20230910105127232

这里在刚开始将cur = dummy_head,是为了将删除头结点的操作和其他结点的操作统一

即永远操作的结点都为cur->next

直到为空,在这个过程中找到要被删除的结点,执行删除操作

复杂度

  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

Code(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_Node = new ListNode(0);
        dummy_Node.next = head;
        ListNode cur = dummy_Node;

        while(cur.next != null){
            if(cur.next.val == val)
            cur.next = cur.next.next;
            else cur  = cur.next;
        }
        return dummy_Node.next;
    }
}

707. 设计链表

思路

这是一个比较综合的题目

get(int index)

这个跟其他链表元素有区别,将cur = d ummyhead->next 是为了解决index等于0的情况,避免没有进入while循环而造成直接返回return cur->val;

addAtHead

在 链表头插入时要注意顺序问题

image-20230910105320233

addAtTail

直接在结尾插入即可

image-20230910105345821
addAtIndex

还是注意插入的顺序问题

image-20230910105438357

deleteAtIndex

找到要删除的结点,将该结点的上一个结点指向下一个结点

image-20230910011347372

时间复杂度

时间复杂度: 涉及 index 的相关操作为 O(index), 其余为 O(1)

空间复杂度: O(n)

Code(C++)

class MyLinkedList {
public:
    struct ListNode{
        int val;
        ListNode* next;
        ListNode(int val):val(val),next(nullptr){}
    };
    MyLinkedList() {
        dummy_head = new ListNode(0);
        _size = 0;
    }
   
    int get(int index) {
        if(index > (_size-1) || index < 0){
            return -1;
        }
        ListNode* cur = dummy_head->next;//要在虚拟头节点的下一个结点,以解决index等于0的情况
        while(index--){
            cur = cur->next;
        }
        return cur->val;

    }
    
    void addAtHead(int val) {
         ListNode* newNode = new ListNode(val);
         newNode->next = dummy_head->next;
         dummy_head->next = newNode; 
         _size++;  
    }
    
    void addAtTail(int val) {
         ListNode* cur = dummy_head;
         ListNode* newNode = new ListNode(val);
         while(cur->next != nullptr){
             cur = cur->next;
         }
         cur->next = newNode;
         _size++;
    }
    
    void addAtIndex(int index, int val) {
        ListNode* newNode = new ListNode(val);
        ListNode* cur = dummy_head;
        if(index > _size) return;
        while(index--){
           cur = cur->next;
        }
         newNode->next = cur->next;//要保证操作的节点是cur->next;
         cur->next = newNode;
        _size++;
    }
    
    void deleteAtIndex(int index) {
        if (index > _size-1 || index < 0) {
            return;
        }
        // 要保证第n个结点一定要是cur->next;
        ListNode* cur = dummy_head;
        ListNode* temp = NULL;
        while(index--){
          cur = cur->next;
        }
        temp = cur->next;
        cur->next = cur->next->next; 
        delete temp;
        temp = nullptr;
        _size--;
    }
private:
    int _size;
    ListNode* dummy_head;
};

/**
 * 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. 反转链表

思路

定义一个temp,来临时存放cur->next,这样在cur->next = pre之后,才能将cur = temp到下一个结点去

image-20230910012140226

Code(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 reverseList(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        ListNode temp = new ListNode();

        while(cur != null){
            temp = cur.next; //因为如果将cur指向pre后就无法找到cur的下一个节点了
            cur.next = pre;
            pre = cur;
            cur = temp;
        }

        return pre;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落雨既然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值