不妨时间换空间(1)

为什么是(1)呢?因为会有2 3 4连续剧啊!后面肯定还会用到这一点,所以这里非常有先见之明地写了(1)哈哈哈哈毫不吝啬地自夸(不愧是我.jpg)
众所周知,时间比空间贵,所以能节约点时间是一点。程序员都摆摊了,,生活不易啊,不想被裁的话赶紧get这个技能吧!
看看现在HR的标准就知道了,以前是能招到人的HR是好HR,现在是裁的多的HR是好HR,恐怖如斯——摆摊吧,程序员!
OMG不要啊,还是拿时间换空间吧~

栗子1

先来看看这个,传送门1

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
注意:保证测试中不会当栈为空的时候,对栈调用pop()或者min()或者top()方法。

啊咧咧?复杂度为O(1)!不会吧??遍历一遍都是O(n)了!求大哥给条活路吧!确实挺傻眼的,刚刚看到这题我人都傻了,停止思考~不可以!停止呼吸也不能停止思考!炭炭可是睡梦中都在全集中!再好好想想!
如果我能再push的时候就记录下当前栈中的最小值呢?然后pop的时候直接弹出去就好,但是!怎么记录呢?好问题!但是又不是问题!逐渐脱离主题。。看看今天的标题《不妨时间换空间》你就明白了,时间复杂度O(1)那么我就牺牲O(n)的空间复杂度,来换取更昂贵的时间!
再定义一个栈!每次主栈push的时候,如果副栈为空就直接也push,否则就比较,如果副栈的栈顶元素更大,就push主栈的这个元素,否则,就把副栈自己的栈顶元素再push一遍。
啊?为什么还要push一遍?省点空间不好吗?
滚回去读题——题目要求的是每次pop的时候都能得到当前栈内的最小值,所以必须要有一个同样大小的空间和主栈实现同步,每一个副栈的元素都记录了从本元素的位置到栈底的最小值。

代码到!

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.stack = []
        self.minValue = []
    def push(self, node):
        self.stack.append(node)
        if self.minValue: # 如果minValue不是空
            if self.minValue[-1] > node:
                self.minValue.append(node)
            else:
                self.minValue.append(self.minValue[-1])
        else:
            self.minValue.append(node)
    def pop(self):
        if self.stack:
            self.minValue.pop()
            return self.stack.pop()
        else:
            return None
    def top(self):
        if self.stack:
            return self.stack.pop()
        else:
            return None
    def min(self):
        if self.minValue==[]:
            return None
        else:
            return self.minValue[-1]

这里说明一下下标为-1表示栈顶元素

栗子2

传送门2

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

有了上面的经验我们知道可以重新开辟一个同样大小的数组,从头到尾遍历原数组,第一轮循环先把奇数放入新数组,第二轮循环再把偶数放入新数组(这样就不会打乱原来的顺序)
但是考虑一下复杂度你会发现这是一个时空都为O(n)的算法——鹅,称不上优秀。

方法1

在这里插入图片描述
但是方法2同样不优秀,只不过思路很新奇,就是给我们之前的冒泡排序赋予了新的用法(奇怪的知识增加了!)
对,我们常用的冒泡是把大的往后交换(往下沉)每轮循环就把当轮循环中最大的元素扔到最后。在这里我们可以每次把偶数往后扔,我们知道,冒泡排序是稳定的排序,所以同样也不会改变元素的相对位置。

方法2

def jiouSort(array):# 奇偶排序
    for j in range(len(array)):
        for i in range(len(array)-j-1):
            if(array[i]%2==0 and array[i+1]%2==1):
                array[i],array[i+1] = array[i+1],array[i] # 夸一下,这个真心好用!
    return array
    
if __name__ == '__main__':
    arr = [8,9,5,6,0]
    arr = jiouSort(arr)
    print(arr)

嗯!今天的内容差不多就这些,然后旋转数组的那题没有用到今天的标题(秉承着不想跑题实则懒得再写的原则)我宣布,那个旋转数组用到的就是一个二分找断崖的思路,二分确实是个好东西~平时也可以用起来!( •̀ ω •́ )y

猜你喜欢

转载自blog.csdn.net/weixin_43905108/article/details/106575328