- 链表反转
给定单链表的头节点 head ,请反转链表,并返回反转后的链表的头节点
-
链表为空,返回头节点
-
定义两个结点 pre 为 null ,cur指向头节点
-
遍历链表时,定义临时结点存放 cur 的下一结点,同时让 cur 指向 pre
-
因为要向后遍历,pre 向后移到 cur 的位置,cur 移到刚刚定义的临时结点位置 (达到链表反转效果) …(以此循环)
-
最后因 cur == null 跳出循环, pre 在cur 的前一位,所以返回 pre 即可
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null) return head;
ListNode pre=null;
ListNode cur=head;
while(cur!=null){
ListNode tmp=cur.next;
cur.next=pre;
pre=cur;
cur=tmp;
}
return 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 mergeTwoLists(ListNode headA, ListNode headB) {
ListNode newHead=new ListNode(-1);
ListNode tmp=newHead;
while(headA!=null&&headB!=null){
if(headA.val<headB.val){
tmp.next=headA;
headA=headA.next;
}else{
tmp.next=headB;
headB=headB.next;
}
tmp=tmp.next;
}
if(headA!=null){
tmp.next=headA;
}
if(headB!=null){
tmp.next=headB;
}
return newHead.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 tmp1=headA;
ListNode tmp2=headB;
int lenA=0,lenB=0;
while(tmp1!=null||tmp2!=null){
if(tmp1!=null){
tmp1=tmp1.next;
lenA++;
}
if(tmp2!=null){
tmp2=tmp2.next;
lenB++;
}
}
if(lenA>lenB){
for(int i=0;i<lenA-lenB;i++){
headA=headA.next;
}
}else{
for(int i=0;i<lenB-lenA;i++){
headB=headB.next;
}
}
while(headA!=null&&headB!=null){
if(headA==headB){
return headB;
}
headB=headB.next;
headA=headA.next;
}
return null;
}
}
- 环形链表
给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。
进阶:
你能用 O(1)(即,常量)内存解决此问题吗?
//思路:快慢指针,有环指定相遇。
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode slow=head;
ListNode fast=head;
while(true){
try{
slow=slow.next;
fast=fast.next.next;
}catch(Exception e){
return false;
}
if(slow==fast){
return true;
}
}
}
}
- 剑指 Offer 25. 合并两个排序的链表
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
示例1
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode newHead=new ListNode(-1);
ListNode tmp=newHead;
while(l1!=null&&l2!=null){
if(l1.val<l2.val){
tmp.next=l1;
l1=l1.next;
}else{
tmp.next=l2;
l2=l2.next;
}
tmp=tmp.next;
}
if(l1!=null){
tmp.next=l1;
}
if(l2!=null){
tmp.next=l2;
}
return newHead.next;
}
}