day3

1、链表理论基础

  1. 链表是以节点的方式来存储的【链式存储】

  2. 每个节点包括data域(存放数据)、指针域(next域、prev域)

    1. next域:指向下一个节点
      1. 最后一个节点的next域为null
    2. prev域:指向上一个节点
      1. 第一个节点的prev域为null
  3. 链表 VS 数组

    1. 链表的各个节点在内存中不一定是连续存储;数组在内存中连续存储
    2. 性能比较

    链表-链表与数据性能对比

2、leetcode203 移除链表元素

  1. 注意:

    1. 创建dummyHead虚拟头节点,作用:表示单链表的头【虚拟头节点不可移动】,指向链表的第一个节点。
    2. 通过一个辅助节点temp,帮助遍历整个链表。
    3. 删除节点时,辅助节点temp定位需删除节点的前一个节点 。
  2. 代码实现

    class Solution {
        public ListNode removeElements(ListNode head, int val) {
            ListNode dummyHead = new ListNode(0);
            dummyHead.next = head;
            ListNode temp = dummyHead;
    
            while(temp.next != null){
                if(temp.next.val == val){
                    temp.next = temp.next.next; 
                } else {
                    temp = temp.next;
                }
            }
    
            return dummyHead.next;
    
        }
    }
    

3、leetcode707 设计链表

class MyLinkedList {
    Node dummyHead;
    int size;

    public MyLinkedList() {
        dummyHead = new Node(0);
        size = 0;
    }
    
    public int get(int index) {
        if(index < 0 || index >= size){
            return -1;
        }

        Node temp = dummyHead.next;
        for(int i=0; i<index; i++){
            temp = temp.next;
        }
        return temp.val;
    }
    
    public void addAtHead(int val) {
        Node addNode = new Node(val);
        addNode.next = dummyHead.next;
        dummyHead.next = addNode;
        size++;
    }
    
    public void addAtTail(int val) {
        Node addNode = new Node(val);
        Node temp = dummyHead;
        while(temp.next != null){
            temp = temp.next;
        }
        temp.next = addNode;
        size++;
    }
    
    public void addAtIndex(int index, int val) {
        if(index > size){
            return;
        }

        Node temp = dummyHead;//定位要添加节点的前一个节点
        Node addNode = new Node(val);

        while(index > 0 ){
            temp = temp.next;
            index--;
        }

        addNode.next = temp.next;
        temp.next = addNode;
        size++;
    }
    
    public void deleteAtIndex(int index) {
        if(index < 0 || index >= size){
            return;
        }

        Node temp = dummyHead; //定位要删除节点的前一个节点
        while(index>0){
            temp = temp.next;
            index--;
        }
        temp.next = temp.next.next;
        size--;
        
    }
}

class Node{
    int val;
    Node next;

    public Node(int val){
        this.val = val;
    }
}

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

4、leetcode206 反转链表

  1. 步骤

    1. 先定义一个新的头节点resverHead,作为翻转后的链表的头

    2. 从头到尾遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表的最前端

  2. 代码实现

    class Solution {
        public ListNode reverseList(ListNode head) {
            ListNode temp = head; //用于遍历原链表的辅助变量
            ListNode tempNext = null; //用于记录temp节点的下一个节点
            ListNode reverseHead = new ListNode(0); //新的头节点
    
            while(temp != null){
                tempNext = temp.next;//每次插入节点操作前,先记录下原链表中当前节点的下一个节点,防止插入操作后temp.next的指向发生改变,无法继续对原链表进行遍历
    
                //每次都从头节点后面开始插入节点
                temp.next = reverseHead.next;
                reverseHead.next = temp;
    
                temp = tempNext;//遍历原链表中的下一个节点,以便插入下一个节点
            }
            
            return reverseHead.next;
            
        }
    }
    
posted @ 2023-01-13 22:37  黄三七  阅读(44)  评论(0)    收藏  举报