LeetCode链表算法题(java版)
Posted 3 ERROR(s)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode链表算法题(java版)相关的知识,希望对你有一定的参考价值。
文章目录
前言
敲敲敲
在写链表的算法题之前先手撕一下链表的几个基本功能吧。(一定要多练习!!!)
class Node
public int data;
public Node next;
public Node(int data)
this.data = data;
public class SingleLinkedList
public Node head;
//头插法
public void addFirst(int data)
Node node =new Node(data);
if(this.head==null)
this.head=node;
return;
node.next=this.head;
this.head=node;
//打印
public void display()
Node cur=this.head;
while(cur!=null)
System.out.print(cur.data);
cur=cur.next;
System.out.println();
//尾插法
public void addEnd(int data)
Node node =new Node(data);
if(this.head==null)
this.head=node;
return;
Node cur=this.head;
while(cur.next!=null)
cur=cur.next;
cur.next=node;
//判断链表中是否存在key值
public boolean contains(int key)
Node cur=this.head;
while(cur!=null)
if(cur.data==key)
return true;
cur=cur.next;
return false;
//得到链表长度
public int size()
Node cur=this.head;
int count=0;
while(cur!=null)
count++;
cur=cur.next;
return count;
//在index(从1开始的)位置插入元素
public void addIndex(int index,int data)
Node note=new Node(data);
if(index==0)
addFirst(data);
return;
if(index==this.size())
addEnd(data);
return;
Node cur=this.head;
while(index-1!=0)
cur=cur.next;
index--;
note.next=cur.next;
cur.next=note;
//删除第一次出现的key值
public void deleteKey(int key)
if(this.head==null)
throw new RuntimeException("链表已经空了");
if(this.head.data==key)
this.head=this.head.next;
return;
Node prev=searchPrev(key);
if(searchPrev(key)==null)
System.out.println("没有要删除的元素");
return;
prev.next=prev.next.next;
private Node searchPrev(int key)
Node prev=this.head;
while(prev.next!=null)
if (prev.next.data == key)
return prev;
else
prev = prev.next;
return null;
//删除所有出现的key值
public void removeAll(int key)
if(this.head==null)
throw new RuntimeException("链表已经空了");
Node prev=this.head;
Node cur=prev.next;
while(cur!=null)
if(cur.data!=key)
prev=prev.next;
cur=cur.next;
else
prev.next=cur.next;
cur=cur.next;
if(this.head.data==key)
this.head=this.head.next;
//清空链表
public void clear()
this.head=null;
一、反转链表
题目:
代码:
class Solution
public ListNode reverseList(ListNode head)
ListNode prev=null;
ListNode cur=head;
ListNode newHead=null;
ListNode curNext=null;
while(cur!=null)
curNext=cur.next;
if(curNext==null)
newHead=cur; 新的链表的头结点就是老链表的头结点
cur.next=prev; 让后面的节点指向前面的节点完成翻转
prev=cur; 前驱节点向后移动
cur=curNext; cur节点向后移动,curNext相当于一个临时变量储存cur的下一个节点,
return newHead;
二、链表的中间节点(力876)
题目:
class Solution
public ListNode middleNode(ListNode head)
ListNode curSlow=head; 快慢指针法,快指针走两下慢指针走一下,
只要快指针不为null(奇数个节点)或者快指针
的下一个节点不为null(偶数个节点)就继续走。
ListNode curFast=head;
while(curFast!=null&&curFast.next!=null)
curSlow=curSlow.next;
curFast=curFast.next.next;
return curSlow;
三、倒数第k个节点(剑22)
题目:
class Solution
public ListNode getKthFromEnd(ListNode head, int k)
ListNode fast=head;
ListNode slow=head;
if(k<=0) k合法性判断
return head;
int n=k-1; 让快指针先走k-1步,然后快慢指针一起走,当快指针.next为null
while(n>0) 则停止。此时slow所指向的位置就是要返回的头结点。
fast=fast.next;
n--; 注意一下循环条件中fast!=null指的是最终fast将指向null,而
fast.next!=null指的是最终fast会指向最后一个节点,这里应该用
while(fast.next!=null) 后者
fast=fast.next;
slow=slow.next;
return slow;
四、分割链表
题目:
class Solution
public ListNode partition(ListNode head, int x)
ListNode bs=null;
ListNode be=null; 创建了四个节点分别指向前链表的头尾结点。后链表的头尾节点。cur
ListNode as=null; 用来遍历原始链表。
ListNode ae=null;
ListNode cur=head;
while(cur!=null) 一个一个遍历所有的节点,小于x的插入到前面的链表,大于等于x
if(cur.val<x) 的插入到后面的链表。
if(bs==null)
bs=cur;
be=cur;
else
be.next=cur;
be=be.next;
else
if(as==null)
as=cur;
ae=cur;
else
ae.next=cur;
ae=ae.next;
cur=cur.next;
if(bs==null) 判断要是前面的链表为空,则返回后面的链表的头结点就行了,注意
if(ae!=null) 把后面链表的尾节点的next置空,不然链表就死循环了。
ae.next=null;
return as;
else 前面的链表要是不为空
be.next=as; 就把前面链表的尾结点和后面链表的头结点链接起来
if(ae!=null)
ae.next=null; 最后把尾结点的next置空
return bs;
五、回文链表
题目:
class Solution
public boolean isPalindrome(ListNode head)
ListNode slow=head;
ListNode fast=head;
// ListNode cur=head;
if(head==null) 当链表为空力扣默认true牛客默认false
return true;
if(head.next==null) 当链表只有一个元素肯定是啦
return true;
while(fast!=null&&fast.next!=null) 我们先根据第二题的方法找到链表的中间节点slow
slow=slow.next;
fast=fast.next.next;
ListNode cur=slow.next; 用cur来遍历从slow开始到null的所有节点,让他们
while(cur!=null) 指向自己前面的节点
ListNode curNext=cur.next; 这里就和反转链表一样了,只不过把前驱结点prev换成
cur.next=slow; 了solw
slow=cur;
cur=curNext;
while(head!=slow)
if(head.val!=slow.val) 这时候slow已经指向最后了,不过他这时候已经被翻转
return false; 往前指向了,只要不相等就不是回文
if(head.next==slow) 判断head.next是不是slow,比如元素个数为偶数1221
return true;
head=head.next; 分别向中间靠拢一个元素
slow=slow.next;
return true;
六、环形链表(力141)
题目:
public class Solution
public boolean hasCycle(ListNode head)
ListNode slow=head; 定义一个快慢指针指向头结点
ListNode fast=head;
while(fast!=null&&fast.next!=null) fast和fast.next都不可以是null,不然就空指针了
fast=fast.next.next; 快指针一次向后移动两个节点
slow=slow.next; 慢指针一次向后移动一个节点
if(fast==slow) 如果快指针和慢指针再次相遇则这是一个环形链表
return true;
return false;
七、两个链表的第一个公共节点(剑52)
题目:
public class Solution
public ListNode getIntersectionNode(ListNode headA, ListNode headB)
int len1=0;
int len2=0;
ListNode cur1=headA;
while(cur1!=null)
len1++;
cur1=cur1.next;
ListNode cur2=headB;
while(cur2!=null)
len2++;
cur2=cur2.next;
cur1=headA;
cur2=headB;
int len=len1-len2;
if(len1<len2)
len=len2-len1; 找到长的链表,让长的链表移动他们差值步
cur1=headB;
cur2=headA;
while(len>0)
cur1=cur1.next;
len--;
while(cur1!=cur2) 当不相等就往后走
cur1=cur1.next;
cur2=cur2.next;
if(cur1==cur2&&cur1!=null) 这个时候他们肯定相等,如果不是null就返回cur1
return cur1;
return null;
八、第一个入环节点(拓展)
题目:
数学分析一下:
public class Solution
public ListNode detectCycle(ListNode head)
ListNode slow=head;
ListNode fast=head;
while(fast!=null&&fast.next!=null)
fast=fast.next.next;
slow=slow.next;
if(slow==fast)break;
if(fast==null||fast.next==null) 找到第一次相遇的地方
return null;
slow=head; 让slow从新指向头
while(fast!=slow) 以相同的速度前进知道下次相遇。
fast=fast.next;
slow=slow.next;
return slow; 第二次相遇的地方就是咱们的入口
九、再熟悉一下链表在ACM模式下的输入输出
static class ListNode
public int val;
ListNode next;
public ListNode(int val)
this.val = val;
public ListNode();
public static void main(String[] args)
ListNode head=new ListNode();
Scanner sc=new Scanner(System.in);
int n=sc.nextInt(); //放在数组中进行单链表的遍历输入
ListNode cur=head;
int[]nums=new int[n];
for (int i = 0; i < n; i++)
nums[i]=scLeetCode与《代码随想录》双指针篇:做题笔记与总结-JavaScript版