目录
1. 反转链表19
if(head==null || head.next==null) return head;
ListNode now =head;
ListNode next = head.next;
ListNode n =null;
while(next!=null){
now.next=n;
n=now;
now=next;
next=next.next;
}
now.next=n;
return now;
2. 翻转指定区间29
public ListNode reverseBetween (ListNode head, int m, int n) {
// write code here
ListNode dummy=new ListNode(-1);
dummy.next=head;
ListNode pre=dummy,p=head;
int index=1;
while(index!=m){
pre=pre.next;
p=p.next;
index++;
}
ListNode tail=p;
while(index<=n){
ListNode temp=p;
p=p.next;
temp.next=pre.next;
pre.next=temp;
index++;
}
tail.next=p;
return dummy.next;
}
3.k个一组翻转40
public ListNode reverseKGroup (ListNode head, int k) {
// write code here
int size=0;
ListNode p=head;
while(p!=null){
size++;
p=p.next;
}
if(size<k) return head;
int index =1;
ListNode n=null;
p=head;
ListNode temp =p;
while(index<=k){
temp=p;
p=p.next;
temp.next=n;
n=temp;
index++;
}
head.next=reverseKGroup(p,k);
return temp;
}
4.合并有序链表47
public ListNode Merge (ListNode pHead1, ListNode pHead2) {
// write code here
ListNode res=new ListNode(-1),p=res;
ListNode p1=pHead1,p2=pHead2;
while(p1!=null && p2!=null){
if(p1.val<=p2.val){
p.next=p1;
p1=p1.next;
}else{
p.next=p2;
p2=p2.next;
}
p=p.next;
}
if(p1==null){
p.next=p2;
}
if(p2==null){
p.next=p1;
}
return res.next;
}
5.合并k个有序00
public ListNode mergeKLists (ArrayList<ListNode> lists) {
// write code here
if(lists.size()==0) return null;
PriorityQueue<ListNode> q=new PriorityQueue<>(lists.size(),(ListNode a,ListNode b)->a.val-b.val);
ListNode res=new ListNode(-1);
for(ListNode p:lists){
if(p!=null)
q.offer(p);
}
ListNode p=res;
while(!q.isEmpty()){
ListNode temp=q.poll();
if(temp.next!=null){
q.offer(temp.next);
}
temp.next=null;
p.next=temp;
p=p.next;
}
return res.next;
}
6.判断是否有环
public boolean hasCycle(ListNode head) {
if(head==null || head.next==null){
return false;
}
ListNode slow=head,fast=head;
slow=slow.next;
fast=fast.next.next;
while(fast!=null && fast.next!=null){
if(slow==fast) return true;
slow=slow.next;
fast=fast.next.next;
}
return false;
}
7.找环的入口18
public ListNode EntryNodeOfLoop(ListNode head) {
if(head==null || head.next==null){
return null;
}
ListNode slow=head,fast=head;
slow=slow.next;
fast=fast.next.next;
while(fast!=null && fast.next!=null){
if(slow==fast) {
return getEntrance(slow,head);
}
slow=slow.next;
fast=fast.next.next;
}
return null;
}
public ListNode getEntrance(ListNode p,ListNode head) {
ListNode slow1=head,slow2=p;
while(slow1!=slow2){
slow1=slow1.next;
slow2=slow2.next;
}
return slow1;
}
8.查找倒数第k个28
public ListNode FindKthToTail (ListNode pHead, int k) {
// write code here
if(pHead==null) return null;
ListNode p1=pHead,p2=pHead;
while(k--!=0){
if(p2==null){
return null;
}
p2=p2.next;
}
while(p2!=null){
p1=p1.next;
p2=p2.next;
}
return p1;
}
9.删除倒数第k个32
public ListNode removeNthFromEnd (ListNode pHead, int k) {
// write code here
if(pHead==null) return null;
ListNode p1=pHead,p2=pHead,dummy=new ListNode(-1),p=dummy;
dummy.next=pHead;
while(k--!=0){
if(p2==null){
return null;
}
p2=p2.next;
}
while(p2!=null){
p1=p1.next;
p2=p2.next;
p=p.next;
}
p.next=p.next.next;
return dummy.next;
}
10.两个链表的第一个节点15
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null ) return null;
int m = getLen(pHead1), n = getLen(pHead2);
ListNode p1 = pHead1, p2 = pHead2;
if (m < n) {
int t = m;
m = n;
n = t;
p1 = pHead2;
p2 = pHead1;
}
while (m != n) {
p1 = p1.next;
m--;
}
while (p1 != p2) {
p1 = p1.next;
p2 = p2.next;
if (p1 == null || p2 == null) return null;
}
return p1;
}
private int getLen(ListNode pHead1) {
// TODO
int m = 0;
ListNode p = pHead1;
while (p != null) {
m++;
p = p.next;
}
return m;
}
11.链表相加 23
public ListNode addInList (ListNode head1, ListNode head2) {
// write code here
ListNode p1 = reverse(head1);
ListNode p2 = reverse(head2);
ListNode res = new ListNode(-1);
ListNode p = res;
int flag = 0;
while (p1 != null && p2 != null) {
int t = p1.val + p2.val + flag;
ListNode temp = new ListNode(t % 10);
flag = t / 10;
p.next = temp;
p = p.next;
p1=p1.next;
p2=p2.next;
}
while (p1 != null ) {
int t = p1.val + flag;
ListNode temp = new ListNode(t % 10);
flag = t / 10;
p.next = temp;
p = p.next;
p1=p1.next;
}
while (p2 != null) {
int t = p2.val + flag;
ListNode temp = new ListNode(t % 10);
flag = t / 10;
p.next = temp;
p = p.next;
p2=p2.next;
}
if(flag!=0){
ListNode temp = new ListNode(flag);
p.next = temp;
p = p.next;
}
res =res.next;
return reverse(res);
}
12.判断链表回文33
public boolean isPail (ListNode head) {
// write code here
if(head==null||head.next==null) return true;
ListNode re=ReverseList(head);
while(re!=null){
if(re.val!=head.val) return false;
re=re.next;
head=head.next;
}
return true;
}
public ListNode ReverseList (ListNode head) {
// write code here
ListNode now =head;
ListNode res = new ListNode(-1);
while(now!=null){
ListNode t = new ListNode(now.val);
t.next=res.next;
res.next=t;
now=now.next;
}
return res.next;
}
13.链表奇偶重排51
public ListNode oddEvenList (ListNode head) {
// write code here
ListNode temp=new ListNode(-1),p=head,dummy=new ListNode(-1);
dummy.next=head;
ListNode pre=dummy,temp_t=temp;
int index=1;
while(p!=null){
if(index%2==0){
ListNode t=p;
pre.next=pre.next.next;
p=p.next;
index++;
t.next=null;
temp_t.next=t;
temp_t=temp_t.next;
}else{
pre=pre.next;
p=p.next;
index++;
}
}
pre.next=temp.next;
return dummy.next;
}
14. 删除重复元素155
public ListNode deleteDuplicates (ListNode head) {
// write code here
if(head==null) return null;
ListNode p=head,n=p.next;
while(n!=null){
if(n.val==p.val){
n=n.next;
p.next=p.next.next;
}
else{
p=p.next;
n=p.next;
}
}
return head;
}
15.删除重复元素202
public ListNode deleteDuplicates (ListNode head) {
// write code here
ListNode dummy=new ListNode(-1);
dummy.next=head;
if(head==null) return null;
ListNode pre=dummy,p=head,n=p.next;
while(n!=null){
int flag=0;
while(n!=null && n.val==p.val){
n=n.next;
flag=1;
}
if(flag==1){
pre.next=n;
p=n;
if(n==null){
break;
}
n=p.next;
}
else{
pre=pre.next;
p=p.next;
n=p.next;
}
}
return dummy.next;
}
16.单链表的排序09
public ListNode sortInList (ListNode head) {
// write code here
PriorityQueue<ListNode> q=new PriorityQueue<>((ListNode a,ListNode b)->a.val-b.val);
ListNode res=new ListNode(-1);
while(head!=null){
ListNode t=head;
head=head.next;
t.next=null;
q.offer(t);
}
ListNode p=res;
while(!q.isEmpty()){
ListNode t=q.poll();
p.next=t;
p=p.next;
}
return res.next;
}
总结:
1. 链表问题主要在于判空和指针复位;
2.判空主要出现在:
1. 初始数据可能为空;
2. 遍历过程中要使用p.val或者p.next的时候p不能为空;
3.特殊一点的for each 遍历的时候也不能为空;
3.指针复位:
下一次判断的时候所有指针要复位;
4.删除需要前指针,第一个节点有时候需要虚拟指针来方便统一操作;
5. 主要知识点:
1.双指针;
2.快慢指针;
3.头插法;
4.指针遍历;
题目来源于: