一、链表理论基础
链表是一种通过指针串联在一起的线性结构,每个节点由两部分组成:数据域和指针域(指向下一个节点),最后一个节点的指针指向NULL(空指针)。 --Carl
链表性能分析:
链表的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;}
}
二、LeetCode 203 移除链表元素
题目链接:203.移除链表元素https://leetcode.cn/problems/remove-linked-list-elements/
思路:先移除符合条件的头结点,再设置虚拟头结点对之后的元素进行移除操作。
/*** 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 = head.next;}ListNode index = head;//删除非头结点while(index != null && index.next != null){if(index.next.val == val){index.next = index.next.next;}else{index = index.next;}}return head;}
}
三、LeetCode 707 设计链表
题目链接:707.设计链表https://leetcode.cn/problems/design-linked-list/
思路:先考虑是否使用头结点,后创建链表节点类,再根据功能要求逐个实现。
//节点类
public class ListNode{int val;ListNode next;public ListNode(){}public ListNode(int val){this.val = val;}
}
class MyLinkedList {ListNode head;int length = -1;//无头结点链表public MyLinkedList() {head = null;length = 0;}public int get(int index) {//下标溢出if(index >= length){return -1;}ListNode temp = head;while(index > 0){index--;temp = temp.next;}return temp.val;}public void addAtHead(int val) {ListNode newNode = new ListNode(val);newNode.next = head;head = newNode;length++;}public void addAtTail(int val) {if(head == null){addAtHead(val);}else{ListNode temp = head;while(temp != null && temp.next != null){temp = temp.next;}ListNode newNode = new ListNode(val);temp.next = newNode;newNode.next = null;length++;}}public void addAtIndex(int index, int val) {if(index > length){return;}if(index == 0){addAtHead(val);return;}if(index == length){addAtTail(val);return;}ListNode newNode = new ListNode(val);ListNode temp = head;while(index > 1){temp = temp.next;index--;}newNode.next = temp.next;temp.next = newNode;length++;}public void deleteAtIndex(int index) {if(index < 0 || index >= length){return;}if(index == 0){head = head.next;length--;return;}ListNode temp = head;while(index > 1){temp = temp.next;index--;}temp.next = temp.next.next;length--;}
}
刚写完出了很多小bug,没有一遍过,说明还是不够熟练,周末加练~
四、LeetCode 206 反转链表
题目链接:206.反转链表https://leetcode.cn/problems/reverse-linked-list/
思路:翻转链表需要记录上一个节点的信息,考虑使用双指针,并设置temp指针暂存信息。
详见代码注释~
/*** 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) {//处理特殊情况if(head == null || head.next == null){return head;}ListNode now = head.next; //now存储当前节点ListNode cur = head; //cur存储上一个节点cur.next = null; //原头结点变尾节点while(now != null){ListNode temp = now.next; //temp存储链表翻转前当前节点的下一个节点now.next = cur; //当前节点的next指向上一个节点cur = now; //cur后移,now变cur,即本次循环的now为下次循环的curnow = temp; //now后移}return cur;}
}
五、今日小结
题目难度逐渐上升,今天耗时较长;时间利用率还是不高,明天争取进一步提升效率~