插入排序 VS 双指针法 ?

Posted 浙江技术救命稻草

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了插入排序 VS 双指针法 ?相关的知识,希望对你有一定的参考价值。


 青涩的我们也曾惧怕它,

       试着接触它、拥抱它、超越它!

作者:浙江宁波李柯迪

题目

给你一个按非递减顺序排序的整数数组nums,返回 每个数字的平方组成的新数组,要求也按非递减顺序排序。

示例 1: 输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100]

示例 2: 输入:nums = [-7,-3,2,3,11] 输出:[4,9,9,49,121]

提示:

  • nums.length
  • nums[i]
  • nums已按 非递减顺序排序

进阶: 请你设计时间复杂度为O(n)的算法解决本问题

来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/squares-of-a-sorted-array著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
面对这道题,你会怎么做呢?

插入排序

插入排序 VS 双指针法 ?

插入排序[1]也称直接插入排序,是一种简单直观的排序算法,通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入,从而使整个序列完全有序。

题解

首先,预设num数组并将nums[0]的平方放入num数组,默认该元素num[0]已经被排序。接着依次遍历nums数组取出每个元素,在已经排序的num数组中从后向前扫描,如果扫描到的元素大于待插入元素,将该元素移到下一位置,直到找到已排序的元素小于或者等于待插入元素的位置,将元素插入到该位置,重复以上步骤,直到将nums数组中的元素全部取出并完成排序!

插入排序 VS 双指针法 ?

Python 代码

# 插入排序方法
nums = list(eval(input("请输入:")))
num = []
num.append(nums[0]**2)
for i in range(1, len(nums)):
    num.append(-1)
    temp = nums[i]**2
    j = i - 1
    while temp < num[j]:
        num[j+1] = num[j]
        j = j - 1
        if j < 0 : break #防止下标越界
    num[j+1] = temp
print(num)
!!!哎呀,运行超出时间限制!

插入排序 VS 双指针法 ?

此处省略...数不清...个元素

还有没有更加高效的算法呢?当然!

双指针法

插入排序 VS 双指针法 ?

双指针指的是在遍历对象的过程中,不是简单的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描。双指针法充分使用了数组的有序特征,从而在某些情况下能够简化一些运算。

题解

我们发现nums数组其实是有序的,但是数组中存在的负数元素在平方以后可能会成为最大值,那么nums数组平方的最大值需要在数组的两端开始查找,不可能出现在中间位置。此时我们就可以考虑双指针法了,定义leftright作为指针,初始化时指针left指向数组的起始位置,指针right指向数组的终止位置。

同时定义一个新的数组num用来存储结果,且新数组num的大小和原数组nums相同,定义指针k用来指向存入的位置,初始化时num数组元素均为-1(因为平方后的值均 ),指针k指向num数组的终止位置。

  • 如果nums[left] * nums[left] < nums[right] * nums[right],那么num[k] = nums[right] * nums[right];

  • 如果nums[left] * nums[left] >= nums[right] * nums[right],那么num[k] = nums[left] * nums[left];

插入排序 VS 双指针法 ?

Python 代码

# 双指针法
nums = list(eval(input("请输入:")))
num = [-1]*len(nums)
left, right, k = 0, len(nums)-1, len(nums)-1 #初始化指针
while left <= right:
    if nums[left]*nums[left] < nums[right]*nums[right]:
        num[k] = nums[right]*nums[right]
        right = right - 1
    else:
        num[k] = nums[left]*nums[left]
        left = left + 1
    k = k -1
print(num)
芜湖!运行通过!时间复杂度O(n)

插入排序 VS 双指针法 ?

课后练习

给你一个有序数组nums,请你原地删除重复出现的元素,使每个元素只出现一次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组 并在使用O(1)额外空间的条件下完成。

示例 1:输入:nums = [1,1,2]  输出:2, nums = [1,2]

示例 2:输入:nums = [0,0,1,1,1,2,2,3,3,4]  输出:5, nums = [0,1,2,3,4]

提示:

  • nums.length
  • nums[i]
  • nums已按升序排列
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

欢迎同学们认真思考,尝试双指针法来解题哦!

可以代码和运行结果私发给小李同学哦

小提示:快慢指针?

本文以讲解算法为主,代码暂且以Python为例,请同学们在搞清楚代码的情况下自行使用其他语言(包含但不限于:VB, C, C++, Java, javascript),欢迎投稿题解哦!

参考资料

[1]

“随机更新的Python入门笔记”之排序基础篇:  

▲ 往期推荐:

©浙江技术救命稻草版权所有 未经允许,请勿转载!


                                             

我是有底线的!『既然滑下来了就别忘了加群插入排序 VS 双指针法 ?


浙江技术救命稻草”答疑·交流“矩阵

记得点亮 “星标” ,不再错过任何干货