一、移除链表元素(LeetCode203)
原链表普通移除,头结点和其它节点方式是不一样的。
/**
* 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 currentHead;//定义一个当前头节点
//判断头结点
while(head!=null&&head.val==val){
head=head.next;
}
currentHead = head;
//判断当前节点及下个节点的值
while(currentHead!=null&¤tHead.next!=null){
if(currentHead.next.val==val){
currentHead.next=currentHead.next.next;
}else{
currentHead=currentHead.next;
}
}
return head;
}
}
使用虚拟头结点进行移除,统一所有节点的移除方式。
首先判断头节点是否为空,不为空则创建虚拟节点,使其虚拟节点的next为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) {
if(head==null){
return head;
}
ListNode dummyHead =new ListNode(-1,head);//创建虚拟头结点
ListNode currentHead;//定义一个临时指针
dummyHead.next=head;
currentHead = dummyHead;
while(currentHead.next!=null){
if(currentHead.next.val==val){
currentHead.next=currentHead.next.next;
}else{
currentHead=currentHead.next;
}
}
return dummyHead.next;
}
}
二、设计链表(LeetCode707)
class ListNode{ //创建链表节点
ListNode next;
int val;
public ListNode(){}
public ListNode(int val){
this.val=val;
}
}
class MyLinkedList {
int size; //链表长度
ListNode dummyhead; //创建虚拟节点
public MyLinkedList() { //初始化
size = 0;
dummyhead =new ListNode(0);
}
//获取第index个节点的数值,注意index是从0开始的,第0个节点就是头结点
public int get(int index) {
//如果index非法,返回-1
if (index < 0 || index >= size) {
return -1;
}
ListNode currentHead = dummyhead; //创建临时指针
//包含一个虚拟头节点,所以查找第 index+1 个节点
for(int i=0;i<=index;i++){
currentHead=currentHead.next;
}
return currentHead.val;
}
//在链表最前面插入一个节点,等价于在第0个元素前添加
public void addAtHead(int val) {
addAtIndex(0, val);
}
//在链表的最后插入一个节点,等价于在(末尾+1)个元素前添加
public void addAtTail(int val) {
addAtIndex(size, val);
}
// 在第 index 个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
// 如果 index 等于链表的长度,则说明是新插入的节点为链表的尾结点
// 如果 index 大于链表的长度,则返回空
public void addAtIndex(int index, int val) {
if (index > size) {
return;
}
if (index < 0) {
index = 0;
}
size++;
ListNode newHead = new ListNode(val);
ListNode currentHead = dummyhead;
for(int i=0;i<index;i++){
currentHead=currentHead.next;
}
newHead.next=currentHead.next;
currentHead.next=newHead;
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
size--;
if (index == 0) {
dummyhead = dummyhead.next;
return;
}
ListNode currentHead = dummyhead;
for(int i=0;i<index;i++){
currentHead=currentHead.next;
}
currentHead.next=currentHead.next.next;
}
}
/**
* 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);
*/
三、反转链表(LeetCode206)
双指针法:创建临时指针指向头指针,前驱指针为空,若当前指针节点非空用一个空节点存储当前指针的下一个节点并使其指针的下一个指向前驱指针,前驱指针指向当前指针,空节点所存储的节点指向当前指针;最后返回反转后的值前驱指针
/**
* 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 current = head;
ListNode tem =null;
while(current!=null){
tem = current.next;
current.next = pre;
pre = current;
current = tem;
}
return pre;
}
}
递归法:借鉴双指针,创建reverse(ListNode prev,ListNode cur)函数进行翻转
/**
* 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) {
return reverse(null, head);
}
private ListNode reverse(ListNode prev, ListNode cur) {
if (cur == null) {
return prev;
}
ListNode temp = null;
temp = cur.next;// 先保存下一个节点
cur.next = prev;// 反转
// 更新prev、cur位置
// prev = cur;
// cur = temp;
return reverse(cur, temp);
}
}