学习了链表的基本操作。
帮助掌握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 removeElements(ListNode head, int val) {
while (head != null && head.val == val) head = head.next;
if (head == null) return null;
ListNode pre = head;
ListNode nex = head.next;
while (nex != null) {
if (nex.val == val) {
nex = nex.next;
pre.next = nex;
} else {
pre = pre.next;
nex = nex.next;
}
}
return head;
}
}
链表基本操作,加上虚拟头节点会好做许多。
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; }
}
class MyLinkedList {
int len;
ListNode head; // 虚拟头节点
public MyLinkedList() {
this.head = new ListNode(-1, null);
len = 0;
}
public int get(int index) {
if (index >= len || index < 0) return -1;
ListNode l = head;
while (l.next != null && index >= 0) {
l = l.next;
index --;
}
return l.val;
}
public void addAtHead(int val) {
ListNode p = new ListNode(val, null);
p.next = head.next;
head.next = p;
len ++;
}
public void addAtTail(int val) {
ListNode p = new ListNode(val, null);
ListNode l = head;
while (l.next != null) {
l = l.next;
}
l.next = p;
len ++;
}
public void addAtIndex(int index, int val) { // 插入下标为index的节点之前
if (index > len || index < 0) return ;
if (index == len) {
addAtTail(val);
return ;
}
ListNode l = head;
while (l.next != null && index > 0) {
l = l.next;
index --;
}
ListNode p = new ListNode(val);
p.next = l.next;
l.next = p;
len ++;
}
public void deleteAtIndex(int index) {
if (index >= len || index < 0) return ;
ListNode l = head;
while (l.next != null && index > 0) {
l = l.next;
index --;
}
l.next = l.next.next;
len --;
}
}
/**
* 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);
*/
刚开始为防止的时间复杂度,先遍历链表把数存到数组,再倒叙遍历数组新建一个链表,时间复杂度,忘记了直接用头插法遍历数组即可反转链表。但是头插法还需要额外的链表空间,空间复杂度较高,因此直接使用了三个指针,在原空间基础上倒转指针指向。
class Solution {
public ListNode reverseList(ListNode head) {
// if (head == null) return head;
// int[] a = new int[5005];
// int i = 0;
// while (head != null) {
// a[i ++] = head.val;
// head = head.next;
// }
// ListNode newHead = new ListNode(a[i - 1], null);
// ListNode l = newHead;
// for (int j = i - 2; j >= 0; j --) {
// ListNode p = new ListNode(a[j]);
// p.next = l.next;
// l.next = p;
// l = l.next;
// }
// return newHead;
// ListNode newHead = new ListNode(-1, null);
// ListNode l;
// while (head != null) {
// l = head;
// head = head.next;
// // 头插法
// l.next = newHead.next;
// newHead.next = l;
// }
// return newHead.next;
ListNode pre = null;
ListNode cur = head;
ListNode temp = null;
while (cur != null) {
temp = cur.next; // 保存下一个节点
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
}