题目链接 &&文章讲解
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点
class Solution {
public ListNode removeElements(ListNode head, int val) {
//头节点为空
if (head == null) {
return head;
}
//头节点的值为val
while (head != null && head.val == val) {
head = head.next;
}
ListNode cur=head;
while(cur.next!=null){
if(cur.next.val==val){
cur.next=cur.next.next;
}else{
cur=cur.next;
}
}
return head;
}
}
class Solution {
public ListNode removeElements(ListNode head, int val) {
//头节点为空
if (head == null) {
return head;
}
//定义虚拟头节点
ListNode dummyHead=new ListNode();
ListNode cur=dummyHead;
dummyHead.next=head;
//判断cur的下一个节点是否为val
while(cur.next!=null){
if(cur.next.val==val){
cur.next=cur.next.next;
}else{
cur=cur.next;
}
}
return dummyHead.next;
}
}
- 直接使用原来的链表来进行删除操作: 由于头节点无前一个节点,因此移除头结点和移除其他节点的操作不同,需要单独操作,将头结点向后移动一位就可以,这样就从链表中移除了一个头结点
- 设置一个虚拟头结点在进行删除操作:虚拟头节点的next为头节点,因此头节点可以使用和移除链表其他节点的方式
题目链接&&文章讲解
你可以选择使用单链表或者双链表,设计并实现自己的链表。
单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。
如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。
实现 MyLinkedList 类:
力扣官方题解
class MyLinkedList {
//链表size
int size;
//虚拟头节点
ListNode head;
class ListNode{
int val;
ListNode next;
ListNode(){}
ListNode(int val) {
this.val=val;
}
}
public MyLinkedList() {
size=0;
head=new ListNode(0);
}
public int get(int index) {
//如果index非法,返回-1
if (index < 0 || index >= size) {
return -1;
}
ListNode cur=head;
for(int i=-1;i<index;i++){
cur=cur.next;
}
return cur.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>size){
return;
}
index = Math.max(0, index);
ListNode pre=head;
for(int i=0;i<index;i++){
pre=pre.next;
}
size++;
ListNode add=new ListNode(val);
add.next=pre.next;
pre.next=add;
}
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
size--;
if (index == 0) {
head = head.next;
return;
}
ListNode pre = head;
for (int i = 0; i < index ; i++) {
pre = pre.next;
}
pre.next = pre.next.next;
}
}
class MyLinkedList {
int size;
ListNode head;
ListNode tail;
class ListNode{
int val;
ListNode prev;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
public MyLinkedList() {
size = 0;
head = new ListNode(0);
tail = new ListNode(0);
head.next = tail;
tail.prev = head;
}
public int get(int index) {
if(index<0||index>=size){
return -1;
}
ListNode cur;
//比较从head还是tail哪个更快找到目标
if(index+1<size-index){//head更快
cur=head;
for(int i=-1;i<index;i++){
cur=cur.next;
}
}else{//tail更快
cur=tail;
for(int i=size;i>index;i--){
cur=cur.prev;
}
}
return cur.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 > size) {
return;
}
index = Math.max(0, index);
ListNode pred, succ;
if(index<size-index){
pred=head;
for(int i=-1;i<index-1;i++){
pred=pred.next;
}
succ=pred.next;
}else{
succ=tail;
for(int i=size;i>index;i--){
succ=succ.prev;
}
pred=succ.prev;
}
size++;
ListNode add=new ListNode(val);
add.prev=pred;
add.next=succ;
pred.next=add;
succ.prev=add;
}
public void deleteAtIndex(int index) {
if (index< 0||index>=size) {
return;
}
ListNode pred, succ;
if (index<size-index) {
pred=head;
for(int i=-1; i<index-1; i++) {
pred=pred.next;
}
succ=pred.next.next;
} else {
succ=tail;
for (int i=size; i>index+1; i--) {
succ=succ.prev;
}
pred=succ.prev.prev;
}
size--;
pred.next=succ;
succ.prev=pred;
}
}
题目链接&&文章讲解
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表
图片来源:力扣题解
从前往后:
从后往前
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null || head.next==null){
return head;
}
ListNode cur=head;
ListNode temp;
ListNode pre=null;
while(cur!=null){
temp=cur.next;
cur.next=pre;
pre=cur;
cur=temp;
}
return pre;
}
}
//递归法1:从前往后
class Solution {
public ListNode reverseList(ListNode head) {
return reverse(null,head);
}
public ListNode reverse(ListNode pre,ListNode cur){
if(cur==null){
return pre;
}
ListNode temp=cur.next;
cur.next=pre;
return reverse(cur,temp);
}
}
//递归法2:从后向前递归
class Solution {
public ListNode reverseList(ListNode head) {
// 边缘条件判断
if(head == null) return null;
if (head.next == null) return head;
//使用递归函数,一直递归到链表的最后一个结点,该结点就是反转后的头结点,记作 retretret
ListNode ret =reverseList(head.next);
//每次函数在返回的过程中,让当前结点的下一个结点的next指针指向当前节点
head.next.next = head;
//同时让当前结点的next指针指向null,从而实现从链表尾部开始的局部反转
head.next = null;
return ret;
}
}
JavaGuide原文链接 && Java面试指北