• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
长发不及肩
博客园    首页    新随笔    联系   管理    订阅  订阅
剑指offer(7)

 

#题目 反转链表。给一个链表,反转链表的顺序

在不添加新链表的条件下,将当前节点的next指针指向当前节点的前一个结点。这种方式需要主义保存当前节点的下一个节点

pre -> node -> next -> next2 变成 pre <- node next -> next2

public ListNode reverseList(ListNode head){

  if(head== null)  return null;

  ListNode next;

  ListNode pre;

  while(head != null){

    next = head.next;

    head.next = pre;

    pre = head;

    head = next;

  }

  return pre;

}

#添加新链表法

遍历当前的链表,将当前节点插入到新链表的头部。相当于倒着顺序生成了链表

保存链表当前节点的next节点,将当前节点的next指针指向新链表的头节点,当前节点替换为保存的next节点

public ListNode reverseList(LiseNode head){

  ListNode next;

  ListNode newNode;

  newNode = head;

  head = head.next;

  while(head != null){

    next = head.next;

    head.next = newNode;

    newNode = head;

    head = next;

  }

  return newNode;

}

 

#题目 合并两个有序链表

两个单调递增的链表,合并为一个单调不减的链表

#非递归 设两个指针,遍历两个数组,小的数字可以确定为当前节点

public ListNode comTwoLists(ListNode left, ListNode right){

  if(left == null || right == null)  return null;

  ListNode head;

  if(left <= right){

    head= left;

    left = left.next;

  }

  else{

    head= right;

    right = right.next;

  }

  ListNode node = head;

  while(left != null && right != null){

    if(left <= right){

      node.next = left;

      left = left.next;

      node = node.next;

    }else{

      node.next = right;

      right= right.next;

      node = node.next;

    }

    if(left != null)

      node.next = left;

    else

      node.next = right;

  return head;

}

#递归法

public ListNode comTwoLists(ListNode left, ListNode right){

  if(left == null)  return right;

  if(right == null)  return left;

  LiseNode head;

  if(left.val < right.val){

    head = left;

    head.next = comTwoLists(ListNode left.next, ListNode right);

  }else{

    head = right;

    head.next = comTwoLists(ListNode left, ListNode right.next);

  }

  return head;

}

当然也可以用优先队列 PriorityQueue 解题,降低算法复杂度

 

#拓展题 合并k个有序链表

方法和上面的类似,每次找到k个链表中最小的节点即可

循环比较k个链表的当前节点,如果当前节点为空则说明该链表已经完成插入。

class Solution {
  public ListNode mergeKLists(ListNode[] lists) {
    if(lists==null||lists.length==0)  return null;
    PriorityQueue<Integer> queue=new PriorityQueue();
    for(ListNode node:lists){
      while(node!=null){
        queue.add(node.val);
        node=node.next;
      }
    }
  ListNode dummy=new ListNode(0);
  ListNode p=dummy;
  while(!queue.isEmpty()){
    ListNode temp=new ListNode(queue.poll());
  p.next=temp;
  p=p.next;
  }
  return dummy.next;
  }
}
————————————————
版权声明:本文为CSDN博主「God_Mood」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
合并k个有序链表的优先队列原文链接:https://blog.csdn.net/God_Mood/java/article/details/87269230

posted on 2020-06-01 00:48  长发不及肩  阅读(84)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3