删除链表元素
删除链表元素有两种方法,一种是链表原地操作,还有一种是虚拟头结点解法,更推荐虚拟头结点解法,在后续的链表问题中,虚拟头结点的方法用的更多
1.链表原地操作
链表原地操作需要考虑的问题就是头结点的删除,在这里有一个比较巧妙的方法,在删除元素的时候先判读是否是删除头结点元素,若是,则将头结点向后移动即可。其他操作没有特殊的地方,就是将要删除结点的上一个结点的next指向要删除结点的下一个结点。
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode node = head; //设置一个指针指向头结点来遍历链表
if(head==null){
return head;
}
while(head!=null&&head.val==val){
head=head.next;
}
while(node!=null&&node.next!=null){
if(node.next.val==val){
node.next = node.next.next;
}else{
node = node.next; //如果当前节点不是目标节点的话,就往后走一位
}
}
return head;
}
}
2.虚拟头结点法
使用虚拟头结点法的话,设置一个遍历指针指向虚拟头结点,则在删除头结点的时候和删除一般结点的操作是一致的,免去了讨论的麻烦
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode dummynode = new ListNode(-1,head); //设置虚拟头结点
if(head==null){
return head;
}
ListNode node = dummynode;
while(node.next!=null){
if(node.next.val==val){
node.next=node.next.next;
}else{
node=node.next;
}
}
return dummynode.next;
}
}
设计链表
该题涉及链表知识较多,需要注意细节
class ListNode{
int val;
ListNode next;
ListNode(){}
ListNode(int val){
this.val = val;
}
}
class MyLinkedList {
int size;
ListNode head;//虚拟头结点
public MyLinkedList() {
size=0;
head = new ListNode(0);
}
public int get(int index) {
if(index<0||index>size-1){
return -1;
}
ListNode cur = head;
while(index!=0){
cur=cur.next;
index--;
}
return cur.next.val;
}
public void addAtHead(int val) {
addAtIndex(0,val);
}
public void addAtTail(int val) {
addAtIndex(size,val); //这里是调用下面的addatindex,不用再size++了
}
public void addAtIndex(int index, int val) {
ListNode newnode=new ListNode(val);
ListNode cur=head; //指向虚拟头结点
if(index>size){
return;
}
if(index==size){ //index==size,直接加在链表末尾
while(cur.next!=null){
cur=cur.next;
}
cur.next=newnode;
}else if(index==0){
newnode.next=cur.next;
cur.next=newnode;
}else{
while(index!=0){
cur=cur.next;
index--;
}
newnode.next=cur.next;
cur.next=newnode;
}
size++;
}
public void deleteAtIndex(int index) {
ListNode cur=head;
if(index<0||index>size-1){
return;
}
if(index==(size-1)){ //假如删除的是尾结点
while(index!=0){
cur=cur.next;
index--;
}
cur.next=null;
}else { //假如删除的不是尾结点
while(index!=0){
cur=cur.next;
index--;
}
cur.next=cur.next.next;
}
size--;
}
}
反转链表
解决反转链表最关键的问题就是将节点的指向反转之后怎么找到下一个结点,这里使用三个指针进行解决
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null){
return head;
}
ListNode pre = new ListNode(0);
ListNode curr=new ListNode(0);
ListNode next=new ListNode(0);
pre=null;
curr=head;
while(curr!=null){
next=curr.next;
curr.next=pre;
pre=curr;
curr=next;
}
head=pre;
return head;
}
}