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

 链表理论基础 

建议:了解一下链接基础,以及链表和数组的区别 

文章链接:代码随想录

  • 链表中的节点在内存中不是连续分布的 ,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。
  • java 初始化:
public class ListNode {
    // 结点的值
    int val;

    // 下一个结点
    ListNode next;

    // 节点的构造函数(无参)
    public ListNode() {
    }

    // 节点的构造函数(有一个参数)
    public ListNode(int val) {
        this.val = val;
    }

    // 节点的构造函数(有两个参数)
    public ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}

 203.移除链表元素  

建议: 本题最关键是要理解虚拟头结点的使用技巧,这个对链表题目很重要。

文章讲解/视频讲解:代码随想录

题目链接:203.移除元素

思路:链表的题目没有很熟悉,链表操作的两种方式:

  • 直接使用原来的链表来进行删除操作。
  • 设置一个虚拟头结点在进行删除操作。
public ListNode removeElements(ListNode head, int val) {
            ListNode dummy =new ListNode(0,head);
            ListNode pre = dummy;
            ListNode cur = head;
        while (cur != null) {
            if (cur.val == val) {
            pre.next = cur.next;
            } else {
            pre = cur;
            }
            cur = cur.next;
        }
        return dummy.next;
        }
/**
 * 添加虚节点方式
 * 时间复杂度 O(n)
 * 空间复杂度 O(1)
 * @param head
 * @param val
 * @return
 */
/**
 * 不添加虚拟节点and pre Node方式
 * 时间复杂度 O(n)
 * 空间复杂度 O(1)
 * @param head
 * @param val
 * @return
 */
public ListNode removeElements(ListNode head, int val) {
    while(head!=null && head.val==val){
        head = head.next;
    }
    ListNode curr = head;
    while(curr!=null){
        while(curr.next!=null && curr.next.val == val){
            curr.next = curr.next.next;
        }
        curr = curr.next;
    }
    return head;
}

 707.设计链表  

建议: 这是一道考察 链表综合操作的题目,不算容易,可以练一练 使用虚拟头结点

文章讲解/视频讲解:代码随想录

题目链接:707. 设计链表

思想:比较复杂,从头开始学习,这道题目设计链表的五个接口:

  • 获取链表第index个节点的数值
  • 在链表的最前面插入一个节点
  • 在链表的最后面插入一个节点
  • 在链表第index个节点前面插入一个节点
  • 删除链表的第index个节点
class MyLinkedList {

    private LinkNode head, tail;
    private int size;


    public MyLinkedList() {
        size = 0;
        head = new LinkNode(-1);
        tail = new LinkNode(-1, head, null);
        head.nxt = tail;
    }
    private LinkNode getNode(int index) {//重点
        if (index < 0 || index >= size) {
            return null;
        }
        LinkNode node;
        if (index > size / 2) {
            node = tail;
            for (int i = 0; i < size - index; i++) {
                node = node.pre;
            }
        } else {
            node = head;
            for (int i = 0; i <= index; i++) {
                node = node.nxt;
            }
        }
        return node;
    }


    public int get(int index) {
        LinkNode node = getNode(index);
        return node == null ? -1 : node.val;
    }
    
    public void addAtHead(int val) {
        head.addRight(new LinkNode(val));
        size++;
    }
    
    public void addAtTail(int val) {
        tail.pre.addRight(new LinkNode(val));
        size++;
    }
    
    public void addAtIndex(int index, int val) {
        if (index <= size) {
            if (index <= 0) {
                addAtHead(val);
            } else if(index == size) {
                addAtTail(val);
            } else {
                getNode(index).pre.addRight(new LinkNode(val));
                size++;
            }
        }
    }

    public void deleteAtIndex(int index) {
        LinkNode node = getNode(index);
        if (node != null) {
            node.pre.delRight();
            size--;
        }
    }
}



class LinkNode {
    int val;
    LinkNode pre, nxt;
    
    public LinkNode(int val) {
        this.val = val;
        this.pre = this.nxt = null;
    }

    public LinkNode(int val, LinkNode pre, LinkNode nxt) {
        this.val = val;
        this.pre = pre;
        this.nxt = nxt;
    }
    void addRight(LinkNode node) {
        node.nxt = this.nxt;
        if (node.nxt != null) {
            node.nxt.pre = node;
        }
        this.nxt = node;
        node.pre = this;
    } 
    void delRight() {
        this.nxt = this.nxt.nxt;
        if (this.nxt != null) {
            this.nxt.pre = this;
        }
    }
}



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

建议先看我的视频讲解,视频讲解中对 反转链表需要注意的点讲的很清晰了,看完之后大家的疑惑基本都解决了。

文章讲解/视频讲解:代码随想录

题目链接:206. 反转链表

思想:比较简单,交换思想

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        ListNode temp = null;
        while(cur != null){
            temp = cur.next;
            cur.next =  pre;
            pre = cur;
            cur = temp;//记住每次都是对前面的补充
        }
        return pre;
    }
}

你可能感兴趣的:(算法刷题,算法,链表,数据结构)