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

链表理论基础

  • 链表几种类型:单链表(指针域只能指向节点的下一个节点),双链表(每个节点有两个指针域,一个指向下一个节点,一个指向上一个节点),循环链表(首尾相连)
  • 链表的存储:链表的节点在内存中并不是连续分布,而是散乱分布在内存的某地址上。
  • 链表的定义
struct ListNode{
    int val;
    ListNode next;
    
    public void ListNode(int val,ListNode next){
        this.val = val;
        this.next = next;
    }
}
  • 链表的操作

删除节点:只需将想删除的节点的前一个结点的next指向想删除的下一个节点即可。

添加节点:先将新节点的next指向下一个节点,再将目标节点的next指向新节点。

插入/删除(时间复杂度)查询适用场景
数组O(n)O(1)数据量固定,频繁查询
链表O(1)O(n)数据量不固定,频繁删减

203.移除链表元素

力扣

解题思路

  • 直接设置一个虚拟表头,然后在设置一个移动表头。当移动节点的下一个节点参数等于目标值时,移动节点的next为下下节点,否则移动移动节点到下一节点。当移动节点的next为空时,说明到了末尾,则跳出循环。

  • 出现的问题:记住要先判断头节点是否为空。

解题代码:

public class Solution {
    public ListNode RemoveElements(ListNode head, int val) {
        if(head == null){
            return null;
        }

        ListNode newNode = new ListNode();
        newNode.next = head;
        newNode.val = -1;
        ListNode moveNode =newNode;

        while(moveNode.next != null){
            if(moveNode.next.val == val){
               moveNode.next=moveNode.next.next;
            }else{

            moveNode = moveNode.next;
            }
        }
        return newNode.next;
    }
}

时间复杂度:O(n)

空间复杂度:O(1)

707.设计链表

public class MyLinkedList {

    int size = 0;
    ListNode dummyHead;

    public MyLinkedList() {
        size = 0;
        dummyHead = new ListNode(-1);
    }
    
    public int Get(int index) {
        if(index < 0 || index >= size){
            return -1;
        }
        //ListNode dummyHead = new ListNode(-1);
        ListNode temp = dummyHead;
        //dummyHead.next = head;
        while(index>0){
            temp = temp.next;
            index--;
        }
        return temp.next.val;
    }
    
    public void AddAtHead(int val) {
        ListNode newNode = new ListNode(val);
        //ListNode dummyHead = new ListNode(-1);
        ListNode temp = dummyHead;
        //dummyHead.next = head;
        newNode.next = dummyHead.next;
        dummyHead.next = newNode;
        size++;
    }
    
    public void AddAtTail(int val) {
       ListNode newNode = new ListNode(val);
       // ListNode dummyHead = new ListNode(-1);
        ListNode temp = dummyHead;
        //dummyHead.next = head;
        while(temp.next != null){
            temp = temp.next;
        }
        temp.next = newNode;
        size++;
    }
    
    public void AddAtIndex(int index, int val) {
        ListNode newNode = new ListNode(val);
        //ListNode dummyHead = new ListNode(-1);
        ListNode temp = dummyHead;
        //dummyHead.next = head;
        if(index > size) return;
        if(index <0) index = 0;
        while(index-->0){
            temp = temp.next;
        }
        newNode.next = temp.next;
        temp.next = newNode;
        size++;
    }
    
    public void DeleteAtIndex(int index) {
        if(index < 0 || index >= size){
            return;
        }
        //ListNode newNode = new ListNode(val);
        //ListNode dummyHead = new ListNode(-1);
        ListNode temp = dummyHead;
        //dummyHead.next = head;
        while(index-->0){
            temp = temp.next;
        }
        temp.next = temp.next.next;
        size--;
    }
}

206.反转链表

public class Solution {
    public ListNode ReverseList(ListNode head) {
        ListNode newNode = null;
        ListNode PrevNode = head;

        while(PrevNode != null){
            ListNode  temp = PrevNode.next; //用临时节点来存储下一节点
            PrevNode.next = newNode; //切断原来节点的联系,并指向反转后的新节点
            newNode = PrevNode; // 改变newNode存储的节点为新节点
            PrevNode = temp; //让旧节点向以前的顺序挪动一位,这样就拆开成两个相反的链
        }
        return newNode;    
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值