java链表相关
节点定义:
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; }
}
节点声明:
ListNode h = new ListNode();
ListNode h = new ListNode(-1);
ListNode h = new ListNode(-1, head);
前两种如果需要使用next节点,需要单独说明
# 203.移除链表元素
总结:虚拟头结点的使用技巧
- 第一次写,出错: 太自信了,完全没带脑子写呢……
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode h = new ListNode(-1, head);
ListNode tmp = h;
while(tmp.next != null) {
if(tmp.next.val == val) {
tmp.next = tmp.next.next;
}
tmp = tmp.next;
}
return h.next;
}
}
- 正确解法:
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode h = new ListNode(-1, head);
ListNode tmp = h;
while(tmp.next != null) {
if(tmp.next.val == val) {
tmp.next = tmp.next.next;
} else {
tmp = tmp.next;
}
}
return h.next;
}
}
707.设计链表
问题:
① java相关链表操作忘干净了。
② 没审题,题目明确说明:假设链表中的所有节点下标从 0 开始。
③ 觉得很奇怪,分不清class ListNode和class MyLinkedList的区别。前者只是定义链表中每个的节点的内容,后者定义的是链表类。
看了思路之后开始写,但报错。
技巧总结:addAtHead、addAtTail可以合并到 addAtIndex方法中
class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) {
this.val=val;
}
}
//注意节点编号从0开始,我们自己设置的head不是第0个
class MyLinkedList {
int size;
ListNode head;
public MyLinkedList() {
head = new ListNode(0);
size = 0;
}
//获取第index个节点的数值,注意index是从0开始的,第0个节点就是头结点
public int get(int index) {
if(index < 0 || index >= size) {
return -1;
}
ListNode cur = head;
//找到第index-1个节点
// 因为index从0开始
for(int i = 0; i < index; i++) {
cur = cur.next;
}
return cur.next.val;
}
public void addAtHead(int val) {
ListNode tmp = new ListNode(val);
tmp.next = head.next;
head.next = tmp;
size++;
}
public void addAtTail(int val) {
ListNode newNode = new ListNode(val);
newNode.next = null;
ListNode cur = head;
while(cur.next!=null) {
cur = cur.next;
}
cur.next = newNode;
size++;
}
public void addAtIndex(int index, int val) {
if( index < 0 || index > size) {
return;
}
ListNode newNode = new ListNode(val);
ListNode cur = head;
for(int i=0; i<index;i++) {
cur = cur.next;
}
newNode = cur.next; //这里写错了,改成newNode.next = cur.next;就可以了
cur.next = newNode;
size++;
}
public void deleteAtIndex(int index) {
if(index < 0 || index >= size) {
return;
}
ListNode cur = head;
for(int i=0; i<index; i++) {
cur = cur.next;
}
cur.next = cur.next.next;
size--;
}
}
206.反转链表
对啦,终于出现写过并改正的题重新写对的情况。
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null) return head;
ListNode p1 = null;
ListNode p2 = head;
// p2.next
ListNode tmp = p2.next;
while(tmp != null) {
p2.next = p1;
p1 = p2;
p2 = tmp;
tmp = tmp.next;
}
p2.next = p1;
return p2;
}
}
优化:
其实while的条件 为 while(p2!=null)更合理,这样还能少一步p2.next = p1;