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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 递归翻转链表 -> 正文阅读

[数据结构与算法]递归翻转链表

迭代的关键

  • precurnext 分别指向需要翻转的区间的 前一个节点当前操作的节点下一个节点

递归的关键

  • 确定递归函数的 输入值功能返回值边界条件,而不是跳入递归函数里面一个个分析(你的脑子里能承受几个函数压入栈的分析?)

反转链表

  • 剑指 Offer II 024. 反转链表
    • head.next.next = head,是为了让当前节点的下一个节点的next指向当前节点
    • head.next = null,则是为了反转链表后头节点的next指向 null变尾节点了
	// 以head为起始节点的链表进行反转,返回反转后的起始节点
	function reverseList(head) {
		if (!head || !head.next) return head;
		let last = reverseList(head.next);
		// 每次反转两个节点
		head.next.next = head;
		head.next = null;
		return last;
	}

反转链表的前n个节点

  • 边界条件 需要 结合n 来判断
  • 反转后头节点变为该部分的尾节点(因为不一定反转整个链表),所以需要 记录第n+1个节点,并让它的next指向它
	// 反转以head为起始节点的前n个节点,返回反转后的起始节点
	let successor = null;
	function reverseN(head,n) {
		if (!head || n == 1) {
			successor = head.next;
			return head;
		}
		let newHead = reverseN(head.next,n - 1);
		head.next.next = head;
		head.next = successor; 
		return newHead;
	}

反转链表的一部分

根据区间进行反转

  • 反转链表 ||
    • left 为1,等价于反转链表的前right个节点,不需要反转的链表部分,无须处理
	// 1 <= left <= right <= 链表长度
	@return: { 反转链表后的头节点 } 
	var reverseBetween = function(head, left, right) {
		// 需要翻转部分
		if (left == 1) {
			return reverseN(head,right);
		}
		// 不需要翻转部分
		head.next = reverseBetween(head.next,left - 1,right - 1);
		return head;	
	};

根据头,尾指针进行反转

	var reverseByPointer = function (head,tail) {
		// 转成单链表反转题
		if (head == tail) return head;
		else if (!head || !tail) return null;
		
		let pre = null;
		while (head != tail) {
			let next = head.next;
			
			head.next.next = head;
			head.next = pre;
			
			head = next;
		}
		return tail;
	}

25. K个一组反转链表

  • 25 . K 个一组反转链表
    • reverseByPointer:负责反转头节点为head,尾节点为tail的链表部分,返回新的头节点和尾节点
    • 用一个 hair节点 来连接头节点,并注意每次翻转链表后需要去修改个别节点即可
	var reverseByPointer = function(head,tail) {
	    let prev = tail.next;
	    let p = head;
	    while (prev != tail) {
	        let next = p.next;
	        p.next = prev;
	
	        prev = p;
	        p = next;
	    }
	    return [tail,head];    
	};
	var reverseKGroup = function(head, k) {
	    let hair = new ListNode(-1);
	    hair.next = head;
	    let pre = hair;
		// 时间复杂度:O(n*n)
	    while (head) {
	        // 记录分区的head,tail节点
	        let tail = pre;
	        for (let i = 0; i < k; i ++) {
	            tail = tail.next;
	            if (!tail) return hair.next;
	        }
	
	        let next = tail.next;
	        [head,tail] = reverseByPointer(head,tail);
	        pre.next = head;
	        tail.next = next;
	
	        pre = tail;
	        head = tail.next;
	    }   
	    return hair.next;
	};
  • 转换成找到每个k区间的头节点进行 reverseN 翻转,注意下标即可
	let succ = null;
	var reverseN = function(head,N) {
	    if (!head) return head;
	    if (N == 0) {
	        // 记录N+1个节点
	        succ = head.next;
	        return head;
	    }
	    let newHead = reverseN(head.next,N - 1);
	    head.next.next = head;
	    head.next = succ;
	    return newHead;
	};
	var reverseBetween = function(head,left,right) {
	    if (left == 0) {
	        return reverseN(head,right);
	    }
	    head.next = reverseBetween(head.next,left - 1,right - 1);
	    return head;
	};
	var reverseKGroup = function(head, k) {
	    // [1,链表长度]
	    // 统计链表的长度
	    let node = head;
	    let len = 0;
	    while (node) {
	        len ++;
	        node = node.next;
	    }
	    // 循环翻转区间
	    let newHead = null;
	    // 时间复杂度:O(n / k * )
	    for (let start = 0,j = 1;(j * k - 1) < len; start += k,j ++) {
	        if (start == 0) {
	            // 0 ~ (k - 1)
	            newHead = reverseN(head,k - 1);
	        } else {
	            // k ~ (2k - 1),2k ~ (3k - 1)等
	            reverseBetween(newHead,start,j * k - 1);
	        }
	    } 
	    return newHead;
	};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-17 13:00:34  更:2021-11-17 13:02:19 
 
开发: 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/26 10:42:24-

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