`
febird
  • 浏览: 256207 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

原地排序与链表翻转

 
阅读更多

有这样一个问题:

有个长度为 n 的 (key,val) 数组 a,其中 key 是 int 类型,并且其值在 [0, n) 之间(前闭后开,包括 0 不包括 n),该数组按 key 是乱序的,但没有重复 key。

要求:对 a 原地按 key 排序,可以使用常数个临时变量,不允许使用其它额外空间,时间复杂度必须是O(n)

我曾经写过另外一个问题:排列的分解(必须看),与此有点类似:但其实不同。


本质的不同在于:那个问题是对循环链表逆时针旋转1个单位,而该问题是要对循环链表顺时针旋转1个单位。逆时针旋转很容易,因为是 forward copy。但是顺时针旋转需要 backward copy,对数组(更 general 一点,是 bidirectional iterator)的 backward copy 很容易,但是对单链表的 backward copy,就比较困难了。

为了解决 backward copy 的问题,我们可以把这个循环链表先进行翻转,然后再 forward copy,思路有了,代码如下:


  • 如果 val 类型的拷贝代价很低(比如象上面demo中的int),可以也可以不用翻转链表,多拷贝两次即可:

在最坏情况下,这个版本对 val 的拷贝次数是上个版本的3倍,但是因为避免了翻转链表,也就减少了多一个循环的开销,这样的循环开销也许会造成大量的cpu cache 失效…… 各有利弊
分享到:
评论

相关推荐

    Python双指针算法模板和题目同向相向快速排序归并排序

    1. **数组去重问题**:通过排序数组,然后用一个快指针和一个慢指针,当快指针找到与慢指针不同的元素时,将该元素移到慢指针的位置,从而实现原地去重。 ```python class Solution: def deduplication(self, nums...

    程序员面试中手写算法的14种“套路”:14 Patterns to Ace Any Coding Interview Quest

    通过改变节点间的指向来实现链表的翻转。 7. 树的广度优先搜索(BFS) BFS常用于遍历树结构,按层次顺序访问节点,如查找最近的公共祖先、构建最小生成树等。 8. 树的深度优先搜索(DFS) DFS通过递归或栈的方式...

    前端工程师算法课 视频教程 下载 因为太大存百度云盘3.zip

    17-二分思想优化排序-快速排序和原地快拍.mp4 18-15题三数之和.mp4 19-二分法优化leftpad函数的性能.mp4 20-回溯和递归思想 01-1-前端为什么要学算法.mp4 01-2-如何把代码提交到github.mp4 02-1一个leetcode...

    前端工程师算法课 视频教程 下载 因为太大存百度云盘4.zip

    17-二分思想优化排序-快速排序和原地快拍.mp4 18-15题三数之和.mp4 19-二分法优化leftpad函数的性能.mp4 20-回溯和递归思想入门 01-1-前端为什么要学算法.mp4 01-2-如何把代码提交到github.mp4 02-1一个...

    前端工程师算法课 视频教程 下载 因为太大存百度云盘2.zip

    17-二分思想优化排序-快速排序和原地快拍.mp4 18-15题三数之和.mp4 19-二分法优化leftpad函数的性能.mp4 20-回溯和递归思想入门 01-1-前端为什么要学算法.mp4 01-2-如何把代码提交到github.mp4 02-1一个...

    前端工程师算法课 视频教程 下载

    20.有效的括号.mp415-71简化路径-强化栈的使用.mp416-算法思想-冒泡排序.mp417-二分思想优化排序-快速排序和原地快拍.mp418-15题三数之和.mp419-二分法优化leftpad函数的性能.mp420-回溯和递归思想入门-46题.mp421-...

    剑指offer中68道例题程序+思路讲解+题目说明.zip

    - **字符串翻转**:如何用原地算法翻转字符串。 - **最长回文子串**:Manacher's Algorithm 解决回文子串问题。 5. **树结构**: - **二叉树遍历**:前序、中序、后序遍历,递归和非递归实现。 - **二叉搜索树*...

    Leetcode答案(c++版)

    - **问题描述**:给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。 - **解题思路**: - 遍历链表,比较当前节点与下一节点的值是否相同。 - 如果相同,则跳过下一节点;如果不相同,则正常移动...

    Leetcode部分试题解析

    6. **Sort Colors**:将一个包含0、1和2的数组原地排序。可以采用双指针策略,让较小的元素向左移动。 7. **Sort List**:对链表进行排序。可以先将链表转换为数组,然后使用快速排序或归并排序,最后将排序后的...

    微软面试(100)题

    - 解答:数组排序可以选择快速排序、冒泡排序等,字符串翻转可直接遍历原地修改,空间复杂度为O(1)。 28. **句子单词顺序翻转**: - 解答:使用栈结构,逐词入栈,再逐词弹出,实现原地翻转。 29. **子字符串...

    C++编程练习.pdf

    8. **数列循环移动**:这涉及到数组元素的位移操作,可以使用额外的数组或原地修改数组完成。 9. **顺序查找**:遍历数组,查找给定值,若找到返回索引,否则返回-1。 10. **数组翻转**:数组元素的顺序反转,可以...

    每日一道编程题精选篇.pdf

    题库可能包括但不限于数组、链表、栈、队列、树、图等数据结构,以及相应的排序、搜索和优化问题。 从【部分内容】来看,以下是一些具体的编程题知识点: 1. 如何使用快慢指针方法快速找到单链表的中间节点。这种...

    LeetCode算法设计

    3. **合并两个链表[E]**:给定两个已排序的链表,合并这两个链表,使之成为一个排序链表。 #### 五、队列和堆栈 **队列和堆栈**是两种基本的数据结构,主要用于管理数据的进出顺序。 1. **数字键盘字母组合问题[M]...

    Leetcode代码以及解答(2)

    - 合并两个已排序的链表。 - **解决方案分析:** - **迭代或递归:** - 比较两个链表的头节点。 - 将较小值节点链接到结果链表。 - 移动较小值节点所在链表的头指针。 - 直至一个链表遍历完,将另一个链表...

    Java 微软面试题

    7. **链表反转**:可以使用迭代或递归方式,改变链表的next指针方向。 8. **atoi函数**:将字符串转换为整数,需要处理前导空格、溢出等情况。 9. **无除法的整数除法**:可以通过乘法和取整来模拟除法。 10. **...

Global site tag (gtag.js) - Google Analytics