203. 移除链表元素
// 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) {
// 在head之前创建一个虚拟节点
ListNode preHead = new ListNode(0, head);
ListNode current=preHead;
while(current.next!=null){
if(current.next.val == val){
current.next=current.next.next;
}else{
current=current.next;
}
}
return preHead.next;
}
}
707.设计链表
class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
class MyLinkedList {
int size;
ListNode head;
public MyLinkedList() {
this.size=0;
this.head=new ListNode(0);//头节点之前的节点
}
public int get(int index) {
if(index<0 || index>=this.size){
return -1;
}
ListNode current=this.head;
for(int i=0;i<=index;i++){
current=current.next;
}
return current.val;
}
public void addAtHead(int val) {
addAtIndex(0, val);
}
public void addAtTail(int val) {
addAtIndex(this.size, val);
}
public void addAtIndex(int index, int val) {
if(index<0 || index>this.size){
return ;
}
ListNode node = new ListNode(val);
ListNode current=this.head;
for(int i=0;i<index;i++){
current=current.next;//最终指向index的前一个节点
}
node.next=current.next;
current.next=node;
size++;//新增元素后不要忘记链表长度+1
}
public void deleteAtIndex(int index) {
if(index<0 || index>=this.size){
return ;
}
ListNode current=this.head;
for(int i=0;i<index;i++){
current=current.next;//最终指向index的前一个节点
}
current.next=current.next.next;
size--;//删除元素后不要忘记链表长度-1
}
}
206.反转链表
/**
* 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) {
if(head==null){
return null;
}
ListNode pre=new ListNode(0, head);//添加首节点
ListNode current=head;
while(current!=null){
ListNode post=current.next;
current.next=pre;
pre=current;
current=post;
}
head.next=null;//去掉首节点
return pre;
}
}
24. 两两交换链表中的节点
/**
* 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 swapPairs(ListNode head) {
if(head==null || head.next==null){
return head;
}
ListNode prehead=new ListNode(0, head);
ListNode node1=head;
ListNode node2=node1.next;
ListNode pre=prehead;
while(node1!=null && node2!=null){
ListNode post=node2.next;
pre.next=node2;
node2.next=node1;
node1.next=post;
pre=node1;
node1=post;
if(node1!=null){
node2=node1.next;
}
}
// 不能直接返回head,因为head现在指向链表的第二个元素
return prehead.next;
}
}
19.删除链表的倒数第 N 个节点
/**
* 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 removeNthFromEnd(ListNode head, int n) {
// 把preHead当成第0个,head当成第1个
ListNode preHead=new ListNode(0, head);
int length=0;
ListNode pointer=preHead;
while(pointer.next!=null){
length++;
pointer=pointer.next;
}
pointer=preHead;
for(int i=1;i<length-n+1;i++){
pointer=pointer.next;//最终指向要删除节点的前一个节点
}
pointer.next=pointer.next.next;
// head节点有可能被删除了
return preHead.next;
}
}
160.相交链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//存放链表A各节点的地址,目的是看链表B中是否有在set集合中的节点
Set set = new HashSet();
ListNode pointerA=headA;
while(pointerA!=null){
set.add(pointerA);
pointerA=pointerA.next;
}
ListNode pointerB=headB;
while(pointerB!=null && !set.contains(pointerB)){
pointerB=pointerB.next;
}
//(1)在最后一个元素之后(null处)跳出循环
//(2)在非空元素处跳出循环
// if(pointerB==null){
// return null;
// }else{
// pointerB;
// }
return pointerB;
}
}
另一种解法:先遍历两个链表,得到它们的长度。然后,让长链表的指针先走它们长度差的步数,接着两个指针同时向前遍历,直到它们相遇或都为 null。
142.环形链表 II
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
Set set=new HashSet();
ListNode pointer=head;
while(!set.contains(pointer) && pointer!=null){
set.add(pointer);
pointer=pointer.next;
}
//(1)链表有环:因走到已经走过的节点而退出循环
//(2)链表无环:因走到链表末尾而退出循环
return pointer;
}
}
另一种解法:快慢指针