珍宝鸭的力扣练习(13):排序算法合集********

1.桶排序(数字之间差值)

桶排序的3个核心问题:
1.每个桶的长度是多少?
我们期望将数组中的各个数等距离分配,也就是每个桶的长度相同,也就是对于所有桶来说,桶内最大值减去桶内最小值都是一样的。
在这里插入图片描述
2.一共要准备多少个桶?
确定桶的数量,最后的加一保证了数组的最大值也能分到一个桶。
在这里插入图片描述
3.如何确定每个数应该对应哪个桶?
我们的做法是要将数组中的数放到一个个桶里面,不断更新更大的(后一个桶内元素的最小值 - 前一个桶内元素的最大值),最后就得到了答案。
在这里插入图片描述
在这里插入图片描述

例题1:相邻元素之间最大的差值

给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。如果数组元素个数小于 2,则返回 0。
输入: [3,6,9,1]
输出: 3
解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。

class Solution(object):
    def maximumGap(self, nums):
        if not nums or len(nums) < 2: return 0
        batch_size = max(1,(max(nums)-min(nums)) // (len(nums)-1))
        batch_num=(max(nums)-min(nums))//batch_size+1
        batch_min=[999999999999 for i in range(batch_num)]
        batch_max = [-999999999999 for i in range(batch_num)]
        batch_has = [0 for i in range(batch_num)]
        for i in range(len(nums)):
            index=(nums[i]-min(nums))//batch_size
            batch_max[index] = max(batch_max[index],nums[i])
            batch_min[index] = min(batch_min[index], nums[i])
            batch_has[index]+=1
        new_batch_max=[]
        new_batch_min=[]
        for i in range(batch_num):
            if batch_has[i]!=0:
                new_batch_max.append(batch_max[i])
                new_batch_min.append(batch_min[i])
        if len(new_batch_max)==1:
            return new_batch_max[0]-new_batch_min[0]
        max_value=-999999999999
        for i in range(1,len(new_batch_max)):
            max_value=max(max_value,new_batch_min[i]-new_batch_max[i-1])
        return max_value

Javascript代码

function MySort( arr ) {
			    // write code here
			    var quicksort = function(arr, low,high){ 
			        var partition = function(arr,low,high){
			            let i = low-1;
			            const pivot = arr[high];
			            for (let j=low;j<high;j++){
			                if (arr[j]<pivot){
			                    i+=1;
			                    let mid = arr[j]
			                    arr[j] = arr[i]
			                    arr[i] = mid
			                }
			            }
			            let mid = arr[i+1]
			            arr[i+1] = arr[high]
			            arr[high] = mid
			            return i+1
			        }
			        let p  = partition(arr, low, high)
					
			        if(p-1>low)
			            quicksort(arr , low,p-1)
			        if (p+1<high)
			            quicksort(arr , p+1,high)
			        
			    }
			    quicksort(arr ,0, arr.length-1)
				return arr
			}

2.快速排序(最小值问题)

该方法的基本思想是:

1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。

题目1:最小的k个数

输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

**题解:**元素位于下标 m,也就是说,左侧的数组有 m 个元素,是原数组中最小的 m 个数。那么:

若 k = m,我们就找到了最小的 k 个数,就是左侧的数组;
若 k<m ,则最小的 k 个数一定都在左侧数组中,我们只需要对左侧数组递归地 parition 即可;
若 k>m,则左侧数组中的 mm 个数都属于最小的 k 个数,我们还需要在右侧数组中寻找最小的 k-m个数,对右侧数组递归地 partition 即可。

class Solution(object):
    def getLeastNumbers(self, arr, k):
        """
        :type arr: List[int]
        :type k: int
        :rtype: List[int]
        """
        if k==0: return []
        def partition(arr, low, high):
            pivot = arr[high]
            i = low - 1
            for j in range(low, high):
                if arr[j] <= pivot:
                    i += 1
                    arr[i], arr[j] = arr[j], arr[i]
            arr[i + 1], arr[high] = arr[high], arr[i + 1]
            return (i + 1)

        def quick_sort(arr, low, high,k):
            p = partition(arr, low, high)
            num=p-low+1
            if k<num:
                quick_sort(arr, low, p - 1,k)
            elif k>num:
                quick_sort(arr, p + 1, high,k-num)


        quick_sort(arr,0,len(arr)-1,k)
        return arr[:k]

题目2:数组排成最小的数

输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
输入: [3,30,34,5,9]
输出: “3033459”
我爱你:字符串排序利用python中的>
仅仅将排序算法修改为:
(str(nums[j])+str(pivot))<=(str(pivot)+str(nums[j])):

class Solution(object):
    def minNumber(self, nums):
        def partition(nums,l,r):
            pivot=nums[r]
            i=l-1
            for j in range(l,r):
                if (str(nums[j])+str(pivot))<=(str(pivot)+str(nums[j])):
                    i+=1
                    nums[i],nums[j]=nums[j],nums[i]

            nums[i+1],nums[r]=nums[r],nums[i+1]

            return i+1
        def quick_sort(nums,l,r):
            p=partition(nums,l,r)
            if p-1>l:
                quick_sort(nums,l,p-1)
            if p+1<r:
                quick_sort(nums, p + 1, r)

        quick_sort(nums,0,len(nums)-1)
        str_nums=[str(i) for i in nums]
        return ''.join(str_nums)

3.归并排序(逆序对问题)

def mergesort(seq):
    """归并排序"""
    if len(seq) <= 1:
        return seq
    mid = len(seq) / 2  # 将列表分成更小的两个列表
    # 分别对左右两个列表进行处理,分别返回两个排序好的列表
    left = mergesort(seq[:mid])
    right = mergesort(seq[mid:])
    # 对排序好的两个列表合并,产生一个新的排序好的列表
    return merge(left, right)

def merge(left, right):
    """合并两个已排序好的列表,产生一个新的已排序好的列表"""
    result = []  # 新的已排序好的列表
    i = 0  # 下标
    j = 0
    # 对两个列表中的元素 两两对比。
    # 将最小的元素,放到result中,并对当前列表下标加1
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result += left[i:]
    result += right[j:]
    return result

题目1:逆序对

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
题解:归并排序:
在这里插入图片描述
如果将数组1【2,3,4,5】与数组2【1,5,6,8】合并,数组1在数组2之前。首先合并2与1中的最小值1。由于2比1大,数组1中的所有数都比1大且都能构成逆序对,逆序对总数加4,以此类推。

class Solution:
    def mergeSort(self, nums, tmp, l, r):
        if l >= r:
            return 0

        mid = (l + r) // 2
        inv_count = self.mergeSort(nums, tmp, l, mid) + self.mergeSort(nums, tmp, mid + 1, r)
        i, j, pos = l, mid + 1, l
        while i <= mid and j <= r:
            if nums[i] <= nums[j]:
                tmp[pos] = nums[i]
                i += 1
                inv_count += (j - (mid + 1))
            else:
                tmp[pos] = nums[j]
                j += 1
            pos += 1
        for k in range(i, mid + 1):
            tmp[pos] = nums[k]
            inv_count += (j - (mid + 1))
            pos += 1
        for k in range(j, r + 1):
            tmp[pos] = nums[k]
            pos += 1
        nums[l:r+1] = tmp[l:r+1]
        return inv_count

    def reversePairs(self, nums: List[int]) -> int:
        n = len(nums)
        tmp = [0] * n
        return self.mergeSort(nums, tmp, 0, n - 1)

4.冒泡排序法

原理代码
时间复杂度为O(N^2)。

def bubbleSort(arr):
    n = len(arr)
 
    # 遍历所有数组元素
    for i in range(n):
 
        # Last i elements are already in place
        for j in range(0, n-i-1):
 
            if arr[j] > arr[j+1] :
                arr[j], arr[j+1] = arr[j+1], arr[j]
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值