算法通关手册 刷题笔记2 数组排序之冒泡排序选择排序

Posted 临风而眠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法通关手册 刷题笔记2 数组排序之冒泡排序选择排序相关的知识,希望对你有一定的参考价值。

算法通关手册 刷题笔记2 数组排序之冒泡排序、选择排序

持续更新中

文章目录

冒泡排序题目 #

题号标题题解标签难度
剑指 Offer 45把数组排成最小的数Python贪心、字符串、排序中等
0283移动零Python数组、双指针简单

剑指 Offer 45 把数组排成最小的数

  • 整了十五分钟,没整出来,想法有许多(写下面注释里面去了)

    class Solution:
        def minNumber(self, nums: List[int]) -> str:
            # 字符串也能比大小
            # 这题需要return
            # 0开头的要剔除吗? 噢噢 题目说不需要
            # 涉及到排列组合哇
            # 冒泡排序其实不一定需要list? 来一个比较一个,就用一个temp变量
            # 如何拼接? 先转字符串再拼接肯定更好
            num2strs = []
            for i in range(len(nums)):
                s = str(nums[i])
                num2strs.append(s)
            # 写一个排列组合的循环?
            # 次数是阶乘啊,这应该也是本题考察的一个关键点吧... 肯定不能这么写
            
            """for i in range(len(nums)):
                for j in range(i+1,len(nums)):"""
            # 上面这是暴力枚举诶,能不能换种想法剪枝,先比较再排序?
            # 放在高位的数字要小,放在低位的数字要大
            # 先把每个数字的最高位数字 比如示例2 ,先比较3 3 3 5 9, 这就有初步的顺序了, 5 和 9 往后放
            # 示例1中 1 和 2 一比较,结果就出来了
            # 比较方法就用冒泡排序
            # 比完第一位,比第二位(次高位)
            # 难搞的就是这种情况 3 、 30、 34, 整个数字位数不一样但是前面有几位是相同的这种情况
            # 我知道了,把3扩充成30  ,且30放在3的前面,34放在3的后面 , 通过3补0可以知道34一定在3的后面,因为12345..9都比0大, 而30就得放3前面了,同理正整数都比0大,330 303,要小的话,肯定要让0在前面啊
            # 不不不,否决刚刚自己的想法, 应该是把3和4拆开来做比较吧, 
            # 举个反例, 54 和 5 ,因为5比4大,所以554 比 545 大,而我们要留下的是更小的数,所以 54 应该放在 5 的前面, 
            # 突然有了一个很大胆的想法,把所有数组都拆成个位数
            # 那么 示例1 就是 [1,0,2] ,
            # 啊不不不 也不行,不能这样搞
            # 再来些例子吧, 比如 54 和 5491, 肯定是545491 比 549154小,那么我们该比较什么,就是那个连接点谁小,连接点会是谁,就两种情况,一个是除去共同前缀之后的串的第一位数,比如这里的91, 另一个就是共同前缀
            # 再来个例子, 54 和 5411 ,因为1比5小,所以 541154比 545411小
            # nice ,nice ,nice
            # 这下子真的找到规律啦!
            # 就是不断对前缀进行冒泡排序!
            
            
            
            return str
    

看题解…

虽说没做出来吧,但我的分析确实沾到边了😎

  • 算法通关手册上的题解

  • orz 是大佬简洁的代码

    import functools
    
    class Solution:
        def minNumber(self, nums: List[int]) -> str:
            def cmp(a, b):
                if a + b == b + a:
                    return 0
                elif a + b > b + a:
                    return 1
                else:
                    return -1
    
            nums_s = list(map(str, nums))
            nums_s.sort(key=functools.cmp_to_key(cmp))
            return ''.join(nums_s)
    

    The method first creates a new list nums_s using list comprehension, which converts each integer in nums to a string. Then it sorts nums_s using a lambda function as the key that concatenates each element with the other and compares them using the cmp function. Finally, the method joins all the elements of nums_s into a single string and returns it.

看看力扣评论区里面的题解

参考链接:https://leetcode.cn/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof/solution/mian-shi-ti-45-ba-shu-zu-pai-cheng-zui-xiao-de-s-4/

来源:力扣(LeetCode)

设数组nums中任意两数字的字符串为x和y,规定判断规则为

  • 若拼接字符串x+y>y+x,则x”大于“y
  • 反之,若x+y<y+x,则x"小于"y

x”小于"y在这里的意思是,x放在y前面比 y放在x前面所得到的数更小,也就是排序完成后,数组中x应该在y左边

再自己写写

  • 这道题被划分到冒泡排序里面了,但是作者用的是内置函数哈哈哈

    • 那么怎样用冒泡排序呢

      class Solution:
          def minNumber(self, nums: List[int]) -> str:
              nums_s = [str(num) for num in nums]
              n = len(nums_s)
              for i in range(n):
                  for j in range(0, n-i-1):
                      if nums_s[j] + nums_s[j+1] > nums_s[j+1] + nums_s[j]:
                          nums_s[j], nums_s[j+1] = nums_s[j+1], nums_s[j]
              return ''.join(nums_s)
      

      其实关键就是,灵活变通一下排序规则, 之前学的最基本的冒泡排序没有加入复杂的规则

      冒泡排序的基本思想是比较相邻的元素,如果第一个比第二个大,就交换它们两个。重复直到整个都排好

      在我的实现中,我使用了冒泡排序的基本比较和交换操作,但是改变了比较的方式,我的实现是比较两个数字的拼接结果的大小,并不是直接比较两个数字本身的大小。这样就能确保拼接后的数字最小的排在最前面。

      冒泡排序的本质就是重复遍历序列,比较相邻元素并进行交换,我在这个思想的基础上实现了自定义比较方式,从而解决了题目中给出的问题。

  • 优化一下刚刚那个冒泡排序!

    I introduced a label called ‘exchanges’ to keep track of whether any elements have been swapped during a pass through the so as to optimize the original code. If no elements have been swapped during a pass, the list is already sorted and the algorithm can stop. This can save time as the algorithm does not need to continue iterating through the entire list when it is already sorted. Add a check before the inner loop, if no exchanges have been made on the previous pass, the list is already sorted and you can break the loop.

    class Solution:
        def minNumber(self, nums: List[int]) -> str:
            nums_s = [str(num) for num in nums]
            n = len(nums_s)
            for i in range(n):
                exchanges = False
                for j in range(0, n-i-1):
                    if nums_s[j] + nums_s[j+1] > nums_s[j+1] + nums_s[j]:
                        exchanges = True
                        nums_s[j], nums_s[j+1] = nums_s[j+1], nums_s[j]
                if not exchanges:
                    break
            return ''.join(nums_s)
    
    
  • 看到了好多高级用法诶,来试试lambda表达式啥的吧

    参考:面试代码题记录3-leetcode179-最大数

    class Solution:
        def minNumber(self, nums: List[int]) -> str:
            strs = list(map(str, nums))
            strs.sort(key = functools.cmp_to_key(lambda x,y: int(x+y) - int(y+x)))
            return ''.join(strs[i] for i in range(len(strs)))
    

    This code is solving the problem by using the built-in sort() method and the ‘key’ argument to sort the array of strings based on the numerical value of the concatenation of each pair of strings.

    The ‘key’ argument takes a function that is used to extract a comparison key from each element in the list, and in this case, it is using the lambda function lambda x,y: int(x+y) - int(y+x) which compares the concatenation of two strings by converting them to integers and subtracting the second concatenation from the first.
    This way, it sorts the array of strings so that the concatenation of any two adjacent strings is always in increasing order.
    After sorting, it’s joining the sorted array of strings into one string and returning it as the final output.
    This is a more concise and pythonic way to solve the problem.

    这段lambda表达式的等价if else语句是咋样的呢,其实就是那个规则函数

    The equivalent of the lambda function lambda x,y: int(x+y) - int(y+x) in an if-else statement would be:

    def compare(x, y):
        if int(x+y) > int(y+x):
            return 1
        elif int(x+y) < int(y+x):
            return -1
        else:
            return 0
    

    This function takes in two strings x and y and compares them by concatenating them and converting them to integers. It returns 1 if the concatenation of x and y is greater than the concatenation of y and x, -1 if it is less than and 0 if they are equal. This function can be used in place of the lambda function in the sort() method with key argument.

    strs.sort(key = functools.cmp_to_key(compare))
    

    It will work in the same way.


    所以lambda函数的返回值的正负是怎么影响sort function的呢?

    The built-in sort() method in Python uses the return value of the function passed to the ‘key’ argument to determine the sort order of the elements in the list.

    The ‘key’ function should return a value that can be used to determine the sort order of the elements.

    In this case, the lambda function lambda x,y: int(x+y) - int(y+x) is passed as the key function, it compares the concatenation of two strings by converting them to integers and subtracting the second concatenation from the first.

    • If the lambda function returns a positive value, it means that the concatenation of the first string x and the second string y is greater than the concatenation of the second string y and the first string x, so the second string will be considered smaller than the first one.
    • If the lambda function returns a negative value, it means that the concatenation of the first string x and the second string y is less than the concatenation of the second string y and the first string x, so the first string will be considered smaller than the second one.
    • If the lambda function returns 0, it means that the concatenation of the first string x and the second string y is equal to the concatenation of the second string y and the first string x, so the sort order of the two strings will not be changed.

    Therefore the lambda function returns a value that is used to determine the sort order of the elements in the list, and the returned value of the lambda function is used to sort the numbers in order of which number when concatenated to the next number is smaller.

0283 移动零

选择排序题目 #

题号标题题解标签难度
0215数组中的第K个最大元素Python数组、堆排序中等

0215 数组中的第K个最大元素

补基础🙅‍

map

The map() function in Python is used to apply a given function to each item in an iterable (e.g. list, tuple, etc.) and returns an iterator that produces the modified items.

  • 前面的剑指Offer 45,里面那个list(map(str, nums))

    • map(str, nums) applies the built-in str() function to each item in the nums list, which converts each integer to a string.
    • The list() function is then used to create a new list from the iterator returned bymap()
  • 来一个使用map() 来使得到列表里面每个元素的平方的例子

    numbers = [1,2,3,4,5]
    squared_numbers = list(map(lambda x: x**2, numbers))
    print(squared_numbers)
    

    This will output: [1, 4, 9, 16, 25]

    In this example, map(lambda x: x**2, numbers) applies a lambda function to each item in the numbers list, which squares the number, and returns an iterator. The list() function is then used to create a new list from the iterator.

  • In general, the syntax(语法) of the map() function is:

    map(function, iterable)
    

functools

  • 还是结合算法通关手册上面给的剑指Offer45的题解来学习

    import functools
    
    class Solution:
        def minNumber(self, nums: List[int]) -> str:
            def cmp(a, b):
                if a + b == b + a:
                    return 0
                elif a + b > b + a:
                    return 1
                else:
                    return -1
    
            nums_s = list(map(str, nums))
            nums_s.sort(key=functools.cmp_to_key(cmp))
            # the `''.join(nums_s)` returns a concatenation of all elements of `nums_s` into a single string.
            return ''.join(nums_s)
    
  • functools is a built-in Python module that contains several useful functions for functional programming. One of the functions in functools is cmp_to_key(), which is used to convert a cmp function to a key function.

    nums_s.sort(key=functools.cmp_to_key(cmp)) uses the built-in sort() method of lists, which sorts the elements of nums_s list in ascending order. The key argument is used to specify a custom function to extract a comparison key from each element. Thefunctools.cmp_to_key(cmp)is passed as the key argument, which converts the cmp function defined within the method to a key function that can be used by thesort() method.

看俩博客仔细学一学lambda表达式

看俩博客仔细学一学lambda表达式

以上是关于算法通关手册 刷题笔记2 数组排序之冒泡排序选择排序的主要内容,如果未能解决你的问题,请参考以下文章

算法通关手册 刷题笔记1 数组基础

Java数组排序算法之直接选择排序

冒泡排序和选择排序

学习数据结构笔记====>不同的排序算法(Sort Algorithm)[冒泡,选择,插入,快速,希尔,基数,归并]

排序算法第一篇(简单桶排选择排序冒泡排序快速排序)

冒泡排序和选择排序