牛客网视频总结3(排序稳定性、计数排序、队列、栈)

牛客网视频总结3

目录)

  • 牛客网视频总结3
  • 排序总结
  • 桶排序(计数排序,计数排序)
    • 计数排序
    • 相邻两数最大差值
  • 队列(先进先出)、栈(后进先出)
    • 用数组结构实现栈:
    • 用数组结构实现队列:
    • getMin函数
    • 用队列结构实现栈
    • 用栈实现队列

排序总结

排序方法 时间复杂度 稳定性 额外空间复杂度 简单介绍
冒泡排序 O ( N 2 ) O(N^2) O(N2) 稳定 - 两两比较交换
选择排序 O ( N 2 ) O(N^2) O(N2) 不稳定 - 选最小的放前面(交换index)
插入排序 O ( N 2 ) O(N^2) O(N2) 稳定 - 前面的先排好,从后往前比
归并排序 O ( N l o g N ) O(NlogN) O(NlogN) 稳定 O ( N ) O(N) O(N) 递归排序,永远先放左边的
快速排序 O ( N l o g N ) O(NlogN) O(NlogN) 不稳定 O ( l o g N ) O(logN) O(logN) 挑一个数放到最后面,<=>
堆排序 O ( N l o g N ) O(NlogN) O(NlogN) 不稳定 - 变成大根堆,和最后一个数换

工程上的综合排序

  • 如果数组装的是基础类型,如int, double, char, float, short,用快排(不要求稳定,快就行)
  • 如果装的是自己定义的类型,如Student,用归并排序(要求稳定)
  • 如果数组很短,长度<60,用插入排序,插入排序常数项小

桶排序(计数排序,计数排序)

  • 非基于比较的排序,与被排序样本的实际数据状况有关,因此很少用
  • 时间复杂度 O ( N ) O(N) O(N),额外空间复杂度 O ( N ) O(N) O(N)
  • 稳定

计数排序

问:已知数组范围0-60,请排序
答:生成新数组[0,0,…,0],长度为61,给每个位置的词频初始化为0,排序时遇到1个2,则2位置上++变为1,又遇到一个2,再++变为2…
桶:1种数据状况出现的词频

相邻两数最大差值

问:给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度 O ( N ) O(N) O(N),且要求不能用非基于比较的排序
答:

  • 数组中N个数,则准备N+1个桶
  • 找最小值和最大值,求差为X,如果X==0,则返回0;如果X!=0,则将X分为N+1份。如最小值0,最大值99,共9个数,则第一个桶范围0-9,第二个桶10-19,第10个桶90-99
  • 数组中的数属于哪个范围则进哪个桶
  • 必存在一个空桶(N个数,N+1个桶),空桶左右相差一定大于一个桶内的相差,因此用下个桶的min-上个桶的max就能计算差值
  • 建三个数组,分别Boolean类型代表桶是否空,min代表每个桶的最小值,max代表每个桶的最大值。
  • 找每个桶的min-左边最近的非空桶的max,求差值最大的即为最大差值(不能先找空桶找左右两侧,会存在19,空,30,49的情况)

队列(先进先出)、栈(后进先出)

用数组结构实现栈:

普通数组,加一个index,index代表新来一个数该放到哪个位置上。入栈index++,出栈index–

用数组结构实现队列:

普通数组,加一个start,加一个end,加一个size。start代表拿一个数,应该拿什么位置上的,end代表新加一个数加在什么位置上,size代表队列长度。

getMin函数

设计两个栈,第一个栈是普通栈,第二个栈是最小值栈。新进栈的>此时最小值,则第二个栈进一个此时最小值的数;新进栈的<此时最小值,则第二个栈进新进栈的这个数。
出栈:左边出一个,右边出一个

class MinStack(object):

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.stack = []
        self.minstack = []


    def push(self, x):
        """
        :type x: int
        :rtype: None
        """
        self.stack.append(x)
        if len(self.minstack) == 0:
            self.minstack.append(x)
        else:
            min_num = min(x, self.minstack[len(self.minstack)-1])
            self.minstack.append(min_num)


    def pop(self):
        """
        :rtype: None
        """
        self.stack.pop()
        self.minstack.pop()


    def top(self):
        """
        :rtype: int
        """
        return self.stack[len(self.stack)-1]


    def min(self):
        """
        :rtype: int
        """
        return self.minstack[len(self.minstack)-1]



# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.min()

用队列结构实现栈

用两个队列,data和help

  • 入栈:新数只进data
  • 出栈:data.size>1,就把所有数都放help里(除最后一个);把data剩下的那个弹出,把help拷贝给data,data改成help
class MyStack(object):

    def __init__(self):
        self.queue = []
        self.help = []


    def push(self, x):
        """
        :type x: int
        :rtype: None
        """
        self.queue.append(x)


    def pop(self):
        """
        :rtype: int
        """
        for i in range(len(self.queue)-1):
            self.help.append(self.queue[i])
        print_num = self.queue[len(self.queue)-1]
        self.queue = self.help
        self.help = []
        return print_num


    def top(self):
        """
        :rtype: int
        """
        return self.queue[len(self.queue)-1]


    def empty(self):
        """
        :rtype: bool
        """
        if len(self.queue)==0:
            return True
        else:
            return False



# Your MyStack object will be instantiated and called as such:
# obj = MyStack()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.top()
# param_4 = obj.empty()

用栈实现队列

两个栈,一个push,一个pop

  • 新数只进push
  • 当pop是空,则一次性将push倒入pop里面;pop里面要是有东西,就不能倒了
  • 用户只从pop里取
class CQueue(object):

    def __init__(self):
        self.stack1 = [];
        self.stack2 = [];


    def appendTail(self, value):
        """
        :type value: int
        :rtype: None
        """
        self.stack1.append(value)


    def deleteHead(self):
        """
        :rtype: int
        """
        if self.stack2 == []:
            while len(self.stack1)!=0:
                self.stack2.append(self.stack1.pop())
        if len(self.stack2)==0:
                return -1;
        else:
            return self.stack2.pop()



# Your CQueue object will be instantiated and called as such:
# obj = CQueue()
# obj.appendTail(value)
# param_2 = obj.deleteHead()

你可能感兴趣的:(算法刷题,排序算法,算法)