目录
反转链表
题目描述:给你单链表的头节点 head
,反转链表,并返回反转后的链表。
问题分析:
我们可以申请三个指针,第一个指针叫 prev,最初是指向 null 的。第二个指针cur 指向 head,然后不断遍历 cur。第三个变量temp是一个临时变量,用来保存cur下一个节点。每次迭代到 cur,都将 cur 的 next 指向 prev,然后 prev 和 cur 前进一位。都迭代完了(cur 变成 null 了),pre 就是最后一个节点了。
代码:
/**
* 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) {
ListNode cur=head;
ListNode prev=null;
ListNode temp=null;
while(cur!=null){
temp=cur.next;
cur.next=prev;
prev=cur;
cur=temp;
}
return prev;
}
}
找链表的中间结点
题目描述:
给定一个头结点为 head
的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
问题分析:
定义一个快指针,一个慢指针,开始都指向头结点,快指针每次走两步,慢指针每次走一步,当快指针变成null了,慢指针指向的位置就是中间结点的位置。
代码:
/**
* 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 middleNode(ListNode head) {
ListNode fast=head;
ListNode slow=head;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
return slow;
}
}
合并两个有序链表
问题描述:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
问题分析: 创建一个新的链表,依次比较两个链表,把小的放入新链表,再往后走一步,如果有一个链表为空,就直接指向另一个链表。
代码:
/**
* 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 mergeTwoLists(ListNode list1, ListNode list2) {
ListNode prevhead=new ListNode(-1);
ListNode prev=prevhead;
while(list1!=null && list2!=null){
if(list1.val<list2.val||list1.val==list2.val){
prev.next=list1;
list1=list1.next;
}else{
prev.next=list2;
list2=list2.next;
}
prev=prev.next;
}
if(list1==null){
prev.next=list2;
}else{
prev.next=list1;
}
return prevhead.next;
}
}
相交链表找公共结点
问题描述:给你两个单链表的头节点 headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null
。
如图就是两个链表相交的情况
题目分析: 先定义一个较长的链表,一个较短的链表,然后求出长度,让长的那个先走它们的长度差步,然后再让它们一起走,相等的时候就是结点的位置。
代码:
/**
* 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) {
if(headA==null||headB==null){
return null;
}
ListNode pl=headA;//长链表
ListNode ps=headB;//短链表
int lenA=0;
int lenB=0;
while(pl!=null){
lenA++;
pl=pl.next;
}
while(ps!=null){
lenB++;
ps=ps.next;
}
pl=headA;
ps=headB;
int len=lenA-lenB;
if(len<0){
pl=headB;
ps=headA;
len=lenB-lenA;
}
for(int i=0;i<len;++i){
pl=pl.next;
}
while(pl!=ps){
pl=pl.next;
ps=ps.next;
}
if(pl==null&&ps==null){
return null;
}
return ps;
}
}
判断是否有环
题目描述:给你一个链表的头节点 head
,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。
题目分析:快慢指针,分别定义一个快指针,一个慢指针,让快指针每次走两步,慢指针每次走一步,如果它们相遇,就说明有环。
代码:
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
if(head==null||head.next==null){
return false;
}
ListNode fast=head;
ListNode slow=head;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
if(fast==slow){
return true;
}
}
return false;
}
}
判断一个链表是否是回文的
题目描述:给定一个head判断这个链表是否是回文的,不是返回false,是返回true;
题目分析:第一步,找到中间结点;第二步,翻转后半部分链表;第三步,判断是否回文
代码:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class PalindromeList {
public boolean chkPalindrome(ListNode A) {
// write code here
if(A==null||A.next==null){
return true;
}
//找到中间结点
ListNode slow=A;
ListNode fast=A;
while(fast!=null&&fast.next!=null){
slow=slow.next;
fast=fast.next.next;
}
//翻转链表
ListNode cur=slow.next;
slow.next=null;
ListNode prev=null;
ListNode next=null;
while(cur!=null){
next=cur.next;
cur.next=prev;
prev=cur;
cur=next;
}
//判断是否回文
while(A!=null&&prev!=null){
if(A.val!=prev.val){
return false;
}
A=A.next;
prev=prev.next;
}
return true;
}
}