最强单链表合集(二)相关题解

一、计算链表中节点个数

  /**
    * @return count 链表中的结点个数
    */
 public static int getLength(Node head) {
  if(head==null) {
      return 0;
  }
  Node temp =head
  int count=0;
  while(temp!=null){
      count++;
      temp=temp.next;
  }
  return count;
 }

二、返回倒数第k个节点

方法一:计算链表中的结点个数sum,然后遍历sum-k次即可.
方法二:通过维护一个定长区间,移动区间右端为空,左端点即为要返回的结点

    /**
     * @param k
     * @param head
     * @return 返回倒数第k个节点
     */
 public Node findIndexNode(int k,Node head){
      if(head.next == null){
          System.out.println("链表为空");
          return:
      }
      int size = getLength(head);
      int num = size-k; //要遍历的次数
      Node temp = head.next;
     for(int i =0;i<num;i++){
         temp=temp.next;
     }
     return temp;
 }
 //方法二
  public Node findIndexNode(int k ,Node head){
   if(head == null){
   return null;
   }
   Node temp = head;
   for(int i = 0 ;i< k-1;i++){
     temp = temp.next;
    }
    Node slow  = head;
    while(temp!=null){
     slow = slow.next;
     temp =temp.next;
    }
    return slow;
  }

三、单链表的反转

public static void reverse(Node head) {
     if(head.next ==null||head.next.next==null){
         return;
     }
     Node cur=head.next;
     Node next=null;
     Node newList=new Node(0);
     while(cur!=null){
         next=cur.next; //next保存下一节点
         cur.next =newList.next; //将cur的下一节点加入新链表的最前端
         newList.next=cur; //当前节点链接到新链表
         cur=next; //cur指向下一节点
     }
     head.next=newList.next;
}

四、从尾到头打印单链表

 public static void reversePrint(Node head) {
        Stack<Node> stack = new Stack();
        Node temp = head;
        //将所有节点压入栈
        while (temp != null) {
            stack.push(temp);
            temp = temp.next;
        }
        //当栈不为空时,弹栈并显示
        while (!stack.isEmpty()){
            System.out.println(stack.pop());
        }
    }

五、删除排序链表中的重复元素

 * 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; }
 * }
public ListNode deleteDuplicates(ListNode head) {
    if(head == null){
        return null;
    }
    ListNode node = head;
    while(node!=null&&node.next!=null){
        if(node.val==node.next.val){
            node.next= node.next.next;
        }
        else{
            node=node.next;
        }
    }
    return head;
    }

六、判断链表是否有环
在这里插入图片描述
快指针比慢指针每次走两步

 * 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; }
 * }
   public boolean hasCycle(ListNode head) {
    if (head == null || head.next == null) {
        return false;
    }
    ListNode slow = head;
    ListNode fast = head.next;
    while (slow != fast) {
        if (fast == null || fast.next == null) {
            return false;
        }
        slow = slow.next;
        fast = fast.next.next;
    }
    return true;
}    

七、返回环形链表中的第一个结点(不带头结点)

 * 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; }
 * }
    public ListNode detectCycle(ListNode head) {
        if( head == null || head.next ==null){
            return null;
        }
        ListNode slow =head;
        ListNode fast= head;
        while(fast!=null){
          slow = slow.next;
          if(fast.next != null){
              fast=fast.next.next;
          }else{
              return null;
          }
          if(fast == slow){
              ListNode temp = head;
              while(temp!=slow){
                  temp=temp.next;
                  slow=slow.next;
              }
              return temp;
          }
        }
        return null;

八、两两交换链表中的结点(不带头结点)
在这里插入图片描述
在这里插入图片描述

 * 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; }
 * }
 public ListNode swapPairs(ListNode head) {
        ListNode pre =new ListNode(0);
        pre.next =head;
        ListNode temp = pre;
        while(temp.next!=null&&temp.next.next!=null){
            ListNode node1 = temp.next;
            ListNode node2=temp.next.next;  
            temp.next= node2;              //交换前后结点
            node1.next =node2.next;
            node2.next =node1;
            temp=node1;
        }
        return pre.next;
    }

九、删除链表中的第n个结点

/**
 * 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 removeNthFromEnd(ListNode head, int n) {
        ListNode temp = new ListNode(0,head);
        int size =len(head);
        int len =size-n;
        ListNode node =temp;
        for(int i = 0;i<len;i++){
         node=node.next;
        }
        node.next=node.next.next;
        return temp.next;
    }
     public int len(ListNode node){
        int sum=0;
        while(node!=null){
            sum++;
            node=node.next;
        }
        return sum;
    }

}

十、给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。

请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。

示例 1:

输入: 1->2->3->4->5->NULL
输出: 1->3->5->2->4->NULL
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

令odd.next=even

/**
 * 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 oddEvenList(ListNode head) {
        if(head ==null)
        return null;        
    ListNode odd = head;
    ListNode even = head.next;
    ListNode temp =even;
    while(temp!=null&&temp.next!=null){
    odd.next = temp.next;
    odd=odd.next;
    temp.next=odd.next;
    temp=temp.next;
        }
   odd.next = even;
   return head;
   }
}

排序链表
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
在这里插入图片描述

/**
 * 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 sortList(ListNode head) {
    if(null == head || null == head.next)
    return head;
    ListNode fast =head;
    ListNode slow =head;
    //根据快慢指针找到中点
    while(fast.next!=null&&fast.next.next!=null){
        slow = slow.next;
        fast= fast.next.next;
    }
    ListNode temp = slow.next;
    slow.next = null; //进行左右分离
    ListNode left =sortList(head); //左边进行排序
    ListNode right =sortList(temp);//排序右边
    ListNode pre = new ListNode(0);
    ListNode res = pre;
    //进行链表合并
    while(left != null &&right != null){
        if(left.val <right.val){
            pre.next =left;
            left =left.next;
        }else{
            pre.next =right;
            right=right.next;
        }
        pre = pre.next;
    }
    if(left == null){
       pre.next =right;
    }else{
        pre.next = left;
    }
    return res.next;
    }
}

链表的回文结构.

先寻找链表的中间节点,然后将后半部分逆置,两边再逐一比较

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class PalindromeList {
    public boolean chkPalindrome(ListNode A) {
        if(A == null){
            return false;
        }
        //找中间节点
        ListNode fast = A;
        ListNode slow = A;
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode cur = slow.next;
        while(cur != null){
                ListNode next = cur.next;
                cur.next = slow;
                 slow = cur;
               cur = next;
        }
        while(A != slow){
        //当链表节点个数为偶数时判断是否w
            if(A.next == slow){
                return true;
            }
            if(A.val != slow.val){
               return false;
            }
             A = A.next;
               slow = slow.next;
        }
        return true;
    }
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值