移除链表元素&&设计链表&&反转链表(Java)

移除链表元素(Java)

做链表相关题目要求返回链表时,只返回头节点即可。

使用原来链表迭代

注意:

  1. 头节点的处理:保证头结点不能为目标值。同时链表中涉及到next,所以时刻关注head.next是不是null(尾结点的next指向null)
  2. 其他节点需要注意进行迭代时,需要用一个临时变量代替head,因为最后要返回head,必须保留。而临时变量代替创建时,不需要单独创建空间,直接ListNode pre = head即可。
/**
 * 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) {
      
      while(head != null && head.val == val){ //妙哉--保证了head不可能为val,但是可以是空
        head = head.next;
      }
      if(head == null){
        return null;
      }
      ListNode pre = new ListNode();
      pre = head; //这两步可以直接合并
      while(pre.next != null){
        if(pre.next.val != val){
            pre = pre.next;
        }
        else{
            pre.next = pre.next.next;
        }
      }
      return head;
    }
}

设置虚拟头节点

方便很多,但是需要创建一个虚拟的头节点,并将其指向head;

/**
 * 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 dummyhead = new ListNode();// 需要创建:原因是目前没有
      dummyhead.next = head;
      ListNode temp = dummyhead;
      if(head == null){
        return null;
      }
      while(temp.next != null){ //先要保证temp本身不是null
        if(temp.next.val == val){
            temp.next = temp.next.next;
        }
        else{
            temp = temp.next;
        }
      }
      return dummyhead.next;
      
    }
}

设计链表(Java)

单链表

注意:

  1. 首先要自己定义一个单链表/双链表类,常定义在外面(所有要使用head都这样);
  2. 定义一个类时有属性方法,属性常常在构造函数中被初始化;
  3. 链表操作的两种方式:直接使用原来的链表来进行操作或设置一个虚拟头结点在进行操作(常采用虚拟节点)
  4. 一旦有了虚拟头结点,就不用对index=0做特殊处理了
  5. 在链表中查找是通过循环不断找到next(只知道头节点); 如果要进行删除和增加操作,需要找到index的前一个
  6. 其他细节见代码
class MyLinkedList {
    private Node head;
    private int size; //链表中实际元素个数

    //初始化指的是初始化属性
    public MyLinkedList() {
        this.size = 0;//(原因是初始化创建的头节点是虚拟的)
        this.head = new Node(0);
    }
    
    public int get(int index) {
        //判断无效情况
        if(index < 0 || index >= size){ // 因此必须要将size作为属性
            return -1; 
        }
        Node temp = head; // 禁止直接使用head
        for(int i = 0; i <= index; i++){
            temp = temp.next;
        }
        return temp.val;
    }
        
    
    public void addAtHead(int val) {
       addAtIndex(0,val);
    }
    
    public void addAtTail(int val) {
       addAtIndex(size,val);
    }
    
    public void addAtIndex(int index, int val) {
        if(index < 0 || index > size){
            return; // 表示直接退出该方法 
        }
        Node newNode = new Node(val); // 需要创建该节点才能加入链表
        Node temp = head;
        for(int i = 0; i < index; i++){ // 当index=0或index=size都可以实现
            temp = temp.next;
        }
        newNode.next = temp.next; //先写后边的
        temp.next = newNode;
        size++; //!!!不要忘记
       }
    
    
    public void deleteAtIndex(int index) {
        if(index < 0 || index >= size){
            return;
        }
        Node temp = head;
        for(int i = 0; i < index; i++){
            temp = temp.next; // 链表中进行查找的核心代码
        }
        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);
 */

双链表不在此赘述,需要注意的是:

  • 需要在初始化时将头尾结点相连
  • 查询时,可以判断index是离头更近还是离尾更近
  • 增加和删除时,一定注意连接方式!!!

反转链表(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;
        while(cur != null){
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }
}

写博客的目的是每日督促并记录刷题,也欢迎大家批评指正~(day3)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值