链表简单习题

24 篇文章 0 订阅
7 篇文章 0 订阅
  • 链表反转

给定单链表的头节点 head ,请反转链表,并返回反转后的链表的头节点

  1. 链表为空,返回头节点

  2. 定义两个结点 pre 为 null ,cur指向头节点

  3. 遍历链表时,定义临时结点存放 cur 的下一结点,同时让 cur 指向 pre

  4. 因为要向后遍历,pre 向后移到 cur 的位置,cur 移到刚刚定义的临时结点位置 (达到链表反转效果) …(以此循环)

  5. 最后因 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;
    }
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

little-peter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值