目录
203.移除链表元素
题目
给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
代码
class Solution {
public ListNode removeElements(ListNode head, int val) {
//方法1 虚拟头节点删除
ListNode first=new ListNode(0);
first.next=head;
ListNode cur=first;
while(cur!=null&&cur.next!=null){
if(cur.next.val==val){
cur.next=cur.next.next;
}else{
cur=cur.next;
}
}
return first.next;
}
}
class Solution {
public ListNode removeElements(ListNode head, int val) {
//方法2 原链表删除持续删除head.val==val的头节点
while(head!=null&&head.val==val){
head=head.next;
}
ListNode cur=head;
//使用cur=head,通过判断cur.next.val==val移除元素
while(cur!=null&&cur.next!=null){
if(cur.next.val==val){
cur.next=cur.next.next;
}else{
cur=cur.next;
}
}
return head;
}
}
707.设计链表
题目
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
代码
//单链表
class ListNode {
int val;
ListNode next;
ListNode(){}
ListNode(int val) {
this.val=val;
}
}
class MyLinkedList {
//size存储链表元素的个数
int size;
//虚拟头结点
ListNode head;
//初始化链表
public MyLinkedList() {
size = 0;
head = new ListNode(0);
}
//获取第index个节点的数值
public int get(int index) {
//如果index非法,返回-1
if (index < 0 || index >= size) {
return -1;
}
ListNode currentNode = head;
//包含一个虚拟头节点,所以查找第 index+1 个节点
for (int i = 0; i <= index; i++) {
currentNode = currentNode.next;
}
return currentNode.val;
}
//在链表最前面插入一个节点
public void addAtHead(int val) {
addAtIndex(0, val);
}
//在链表的最后插入一个节点
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 pred = head;
for (int i = 0; i < index; i++) {
pred = pred.next;
}
ListNode toAdd = new ListNode(val);
toAdd.next = pred.next;
pred.next = toAdd;
}
//删除第index个节点
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
size--;
ListNode pred = head;
for (int i = 0; i < index; i++) {
pred = pred.next;
}
pred.next = pred.next.next;
}
}
206.反转链表
题目
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
代码
递归做法
class Solution {
public ListNode reverseList(ListNode head) {
/* 递归知识
1.确定递归函数的参数和返回值
2.确定终止条件
3.确定单层递归的逻辑
*/
return reverse(null,head);
}
public ListNode reverse(ListNode pre,ListNode curr){
if(curr==null){
return pre;
}
ListNode node=curr.next; //保存下一个节点
curr.next=pre; //反转
return reverse(curr,node);
}
}
迭代法
class Solution {
public ListNode reverseList(ListNode head) {
//根据后入先出的特点想到了栈,用LinkedList去实现
if(head==null){
return null;
}
LinkedList<ListNode> list=new LinkedList<>();
while(head!=null){
list.addFirst(head);
head=head.next;
}
int len=list.size();
for(int i=0;i<len-1;i++){
ListNode node1=list.get(i);
ListNode node2=list.get(i+1);
node1.next=node2;
}
//原来的1->2,后面在栈中反转了2->1,因此还存在环,需要将1的next设为null
list.get(len-1).next=null;
return list.get(0);
/*迭代*/
if(head==null){
return null;
}
ListNode pre=null;
ListNode curr=head;
while(curr!=null){
ListNode node=curr.next; //暂存下一节点
curr.next=pre; //建立next指针关系
pre=curr; //将curr的地址赋值给pre
curr=node; //将curr指向next节点
}
return pre;
}
return reverse(null,head);
}