IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 链表相关力扣·算法题 -> 正文阅读

[数据结构与算法]链表相关力扣·算法题

一、链表

(1)链表逆序206

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

思路:依次遍历链表节点,每遍历一个节点,反转一个节点。

var reverseList = function(head) {
    let newHead = null;
    let next = head;
    while(head){
        next = head.next;
        head.next = newHead;
        newHead = head;
        head = next;
    }
    return newHead;
};

(2)链表逆序进阶版92

 //分了三段式,找到头结点的前驱,尾节点的后继,把中间的部分反转,再拼接起来
var reverseBetween = function(head, left, right) {
    let preNode = null;
    let changeLen = right - left + 1;
    let next = null;
    let newHead = null;
    let result = head;
    while(head&&--left){
        preNode = head;
        head = head.next;
    }//头结点的前驱部分
    let reverseTailNode = head;//反转前的头结点;反转后的尾节点
    while(head&&changeLen){
        next = head.next;
        head.next = newHead;
        newHead = head;
        head = next;
        changeLen--;
    }
    reverseTailNode.next = head;
    if(preNode){
        preNode.next = newHead;
    }else{
        result = newHead
    }
    return result;
}

(3)求相交链表160

给你两个单链表的头节点 headAheadB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null

解法一:利用set类,set类比较的是堆里面的地址,可以将headA插入到set类中,再用set类的has方法判断headB的节点是否在set类中。

var getIntersectionNode = function(headA, headB) {
    let setA = new Set();
    while(headA){
        setA.add(headA)
        headA = headA.next
    };
    while(headB){
        if(setA.has(headB)){
            return headB
        }
        headB = headB.next
    }
};

解法二:计算出两个链表的长度,找出多余的部分。将长链表指针移动到和较短链表对应的位置。headA和headB同时向后移动,如果headA===headB,就返回当前节点。

 var getNodeLength = function(head){
    let length = 0;
    while(head){
        length++;
        head = head.next;
    }
    return length;
}
var removeHeadNode = function(head,length){
    length = Math.abs(length);
    while(head&&length){
        head = head.next;
        length--;
    }
    return head;
}
var getIntersectionNode = function(headA, headB) {
  let lengthA = getNodeLength(headA);
  let lengthB = getNodeLength(headB);
  let otherLength = lengthA - lengthB;
  if(otherLength < 0){
      headB = removeHeadNode(headB,otherLength)
  }else{
      headA = removeHeadNode(headA,otherLength)
  }
  while(headA&&headB){
      if(headA===headB){
          return headA;
      }else{
          headA = headA.next;
          headB = headB.next;
      }
  }
  return null;
};

(5)链表划分,链表分隔86

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。你应当 保留 两个分区中每个节点的初始相对位置。
解法:利用两个临时头结点,less_head和more_head,分别记录小于和大于等于x的链表,然后用less_ptr和more_ptr遍历,最后拼接起来并把more_ptr置空,再返回less_head.next。

var partition = function(head, x) {
  let less_head = new ListNode(null);
  let more_head = new ListNode(null);
  let less_ptr = less_head;
  let more_ptr = more_head;
  while(head){
      if(head.val < x){
          less_ptr.next = head;
          less_ptr = head;
      }else{
          more_ptr.next = head;
          more_ptr = head;
      }
      head = head.next;
  }
  less_ptr.next = more_head.next;
  more_ptr.next = null;
  return less_head.next;
};

(6)复杂链表实现深拷贝

(7)2个排序列表的合并

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

img
思路:创建一个新的头结点,比较两个链表相同长度的部分,再判断head1和head2是否有剩余,如果有,拼接在新链表之后即可。

var mergeTwoLists = function(list1, list2) {
    let newHead = new ListNode(null);
    let new_ptr = newHead;
    while(list1&&list2){
        if(list1.val <= list2.val){
            new_ptr.next = list1;
            new_ptr = new_ptr.next;
            list1 = list1.next;
        }else{
            new_ptr.next = list2;
            new_ptr = new_ptr.next;
            list2 = list2.next;
        }
    }
     if(list1){
        new_ptr.next = list1;
    }
    if(list2){
        new_ptr.next = list2;
    }
    return newHead.next;
};

(8)多个有序链表的排序

给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
  1->4->5,
  1->3->4,
  2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

解法一:
将k*n个链表的节点放到一个数组中,对这个数组中的val进行排序,排序之后连接起来,返回合并之后的头结点。

var mergeKLists = function(lists) {
    let node_vec = [];
    let ptr = lists[0]
    for(var i=0;i<lists.length;i++){
         ptr = lists[i];
         while(ptr){
            node_vec.push(ptr);
            ptr = ptr.next;
        }
    }
    node_vec.sort((a,b)=>{return a.val-b.val})
    for(var i=1;i<node_vec.length;i++){
        node_vec[i-1].next = node_vec[i]
    }
    node_vec[node_vec.length-1]!=undefined?node_vec[node_vec.length-1].next=null:node_vec[0]=null
    return node_vec[0]
};

解法二:对k个链表进行分治,两两进行合并。也就是将lists分为两个数组,分别递归合并,最后将两个数组再合并(!!!注意js除法除出来是浮点数,要向下或者向上取整)

 var mergeTwoLists = function(list1, list2) {
    let newHead = new ListNode(null);
    let new_ptr = newHead;
    while(list1&&list2){
        if(list1.val <= list2.val){
            new_ptr.next = list1;
            new_ptr = new_ptr.next;
            list1 = list1.next;
        }else{
            new_ptr.next = list2;
            new_ptr = new_ptr.next;
            list2 = list2.next;
        }
    }
    if(list1){
        new_ptr.next = list1;
    }
    if(list2){
        new_ptr.next = list2;
    }
    return newHead.next;
};
var mergeKLists = function(lists) {
    if(lists.length === 0){
        return null;
    }
    if(lists.length === 1){
        return lists[0];
    }
    if(lists.length === 2){
        return mergeTwoLists(lists[0],lists[1]);
    }
    let mid = Math.floor(lists.length/2);
    let list1 = [];
    let list2 = [];
    for(let i = 0;i<mid;i++){
        list1.push(lists[i])
    }
    for(let i = mid;i<lists.length;i++){
        list2.push(lists[i])
    }
    let ptr1 = mergeKLists(list1);
    let ptr2 = mergeKLists(list2);
    return mergeTwoLists(ptr1,ptr2)
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-09-25 23:20:35  更:2022-09-25 23:20:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 20:45:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码