荣耀社招笔试

荣耀社招笔试题纪录篇

原文链接荣耀社招笔试题

十一放假回家参加了荣耀社招笔试,两道算法题,解析仅供参考

第一题:旋转矩阵

题目描述:

给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请
你设计一种算法,将图像旋转 90 度。不占用额外内存空间能否做到?

示例 1:

给定 matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

原地旋转输入矩阵,使其变为:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]
示例 2:

给定 matrix =
[
  [ 5, 1, 9,11],
  [ 2, 4, 8,10],
  [13, 3, 6, 7],
  [15,14,12,16]
], 

原地旋转输入矩阵,使其变为:
[
  [15,13, 2, 5],
  [14, 3, 4, 1],
  [12, 6, 8, 9],
  [16, 7,10,11]
]

分析

作为数学系出生的学生,对矩阵的操作应该有所印象,本题的本质在于考察对于矩阵的基本运算能力,例如矩阵转置、内积、点积以及矩阵的迹、特征值和特征向量等等,这是解决本题以及类似题的关键,也是刷题过程中从仅仅刷题到总结经验的思考过程,发现自己目前欠缺的正是这个思考过程。

记得很清,在18年找实习的时候,人生中第一次求职面试公司是阿里,面试官在结束面试时给我说,“任何语言你应该看其本质,你是数学系的,你应该知道事物的本质,框架都是基于语言的本质搭建的”,这句话当时记得很清,很清楚其中的分量,很遗憾当时不能立即运用到实际开发学习之中,因为自己一直缺乏深入的思考,正如姜同学所说,“你在学校时候虽然也跟我们一起学,当你自己思考的太少了”,正因如此,走出学校去实习开始那一刻,和大部队渐行渐远,导致如此境地。思考,是突破瓶颈追求进步的必经之路,实操是检验思考的唯一标准,是及时反馈思考结果的不二法门。

回到本题,矩阵运算,就是通过转换操作把一个矩阵转为另一个矩阵,力扣原题是顺时针转换90度,荣耀笔试是顺时针转换m次,透过现象看本质,转换m次就是转换m个90度,循环即可。笔者当时在做这道题时观察转换后坐标和原坐标的关系,找出共同之处,这是思考欠缺的点,应该从更高的维度思考本题,基于做题的敏感性,联想矩阵的特征,n阶亦有诸多特征。

代码解析

"""
@Auth : Mario
@Date : 2021/10/4 21:43
@Version :
@Description :旋转矩阵
"""

class Solution:
    def rotate(self, matrix) -> None:
        n = len(matrix)
        # 水平翻转
        i = 0
        j = n -1
        while i < j:
            # 每一列上下翻转
            for k in range(n):
                matrix[i][k], matrix[j][k] = matrix[j][k], matrix[i][k]
            i += 1
            j -= 1

        # 对角线翻转
        for x in range(n):
            for y in range(x):
                matrix[x][y], matrix[y][x] = matrix[y][x], matrix[x][y]

    def rotate2(self, matrix) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """

        # 方法二
        l = len(matrix)
        # 先以对角线(左上-右下)为轴进行翻转
        for i in range(l - 1):
            for j in range(i+1,l):
                temp = matrix[i][j]
                matrix[i][j] = matrix[j][i]
                matrix[j][i] = temp

        # 每一行中点两边交换元素交换
        mid = l >> 1
        for i in range(l):
            for j in range(mid):
                temp = matrix[i][j]
                matrix[i][j] = matrix[i][l-1-j]
                matrix[i][l-1-j] = temp

    # 方法三: 多使用一个矩阵,内存较大
    def rotate2(self, matrix) -> None:

        n = len(matrix)
        matrix_ = [i.copy() for i in matrix]
        for i in range(n):
            for j in range(n):
                matrix_[j][n-1-i] = matrix[i][j]
        # 注意这里是引用拷贝 不能写成 matrix = matrix_
        matrix[:] = matrix_


    # 翻转m次
    def num(self, matrix, m):
        while m > 0:
            self.rotate(matrix)
            m -= 1
        print([x for x in matrix])

if __name__ == '__main__':
    s = Solution()
    m = [[1,2,3],[4,5,6],[7,8,9]]
    s.num(m, 3)

第二题:1702. 修改后的最大二进制字符串

题目描述:

给你一个二进制字符串 binary ,它仅有 0 或者 1 组成。你可以使用下面的操作任意次对它进行修改:

操作 1 :如果二进制串包含子字符串 “00” ,你可以用 “10” 将其替换。
比方说, “00010” -> “10010”

操作 2 :如果二进制串包含子字符串 “10” ,你可以用 “01” 将其替换。
比方说, “00010” -> “00001”

请你返回执行上述操作任意次以后能得到的 最大二进制字符串 。如果二进制字符串 x 对应的十进制数字大于二进制字符串 y 对应的十进制数字,那么我们称二进制字符串 x 大于二进制字符串 y 。

示例 1:

输入:binary = "000110"
输出:"111011"
解释:一个可行的转换为:
"000110" -> "000101" 
"000101" -> "100101" 
"100101" -> "110101" 
"110101" -> "110011" 
"110011" -> "111011"
示例 2:

输入:binary = "01"
输出:"01"
解释:"01" 没办法进行任何转换。

分析

本题通过二进制变换找到最大的二进制数,第一个‘0’之前的1全部不动,之后的1全部移到末尾,'00’通过转换变为‘10’

代码解析

class Solution:
    def maximumBinaryString(self, binary: str) -> str:
        pass
        # 自己写的:完全没有深入琢磨题的意思
        # l = len(binary)
        # if l <= 1:
        #     return binary
        # i = l - 2
        # while binary[i] == '1' and i >= 0:
        #     for i in range(i,l):
        #         i -= 1
        # j = 0
        # while j < i and binary[j:j+2] == "00":
        #     binary[i:i+2] = "10"
        #     j += 1
        # return binary
        # 
        # num = 0
        # start = 0
        # for i in range(l):
        #     if binary[i] == '0':
        #         num += 1

    # 方法二:失败
    def maximumBinaryString2(self, binary: str) -> str:
        l = len(binary)
        left = 0 # 左边1 的个数
        right = 0 # 右边1的个数
        flag = True
        for i in range(l):
            flag = (flag and binary[i] == "1")
            left += (flag and binary[i] == '1')
            right += (not flag and binary[i] == '1')

        if left + right < l -1:
            for i in range(l):
                k = l - 1 - right
                if i == k:
                    binary[i] = '0'
                else:
                    binary[i] = '1'
                # binary[i] = (i == k ? '0' : '1' )
        return binary

    # 方法三:通过统计0 两边1的个数确定
    def maximumBinaryString3(self, binary: str) -> str:
        import collections

        l = len(binary)
        high1 = 0
        start1 = 0
        for i in range(l):
            if binary[i] == '0':
                break
            # high1 统计第一个0 之前连续1 的个数
            high1 += 1

        # 此方法用于用于计数可哈希对象,返回一个dict 类型,统计每个数据的个数, 多学习呀
        num = collections.Counter(binary)
        if num['0'] == 0:
            return binary
        # 统计第一个0 之后1的个数
        end1 = num['1'] - high1
        # 由00 -> 10 转换后1的个数
        start1 = l - 1 - end1
        return '1' * start1 + '0' + '1' * end1

    # 方法四: 统计第一个0前面1的个数,和0的个数
    def maximumBinaryString3(self, binary: str) -> str:
        l = len(binary)
        start = -1
        cnt = 0
        for i in range(l):
            if binary[i] == '0':
                cnt += 1
                if start == -1:
                    # 记录从第一位开始连续是1的个数
                    start = i
        # 此时全部是1
        if start == -1:
            return binary
        #第一个0 后面1的个数:
        end = l - start - cnt
        # 此时有cnt 个0,这经过000...0 -> 111...0转换后有(cnt - 1)个1,1个0
        return '1' * start + '1' * (cnt - 1) + '0' + '1' * end

if __name__ == '__main__':

    s = "hello"
    # s[0:2] = "11" # 语法错误,string 是不可变类型
    print(s)
    print(s[0:2])
    print(s[-1])

    left = 0
    flag = True
    left += flag and s[0] == 'h'
    print("flag and s[0] == 'h': ", flag and s[0] == 'h') # flag and s[0] == 'h':  True
    print(1 + True) # 2
    print("left: ",left) # left:  1
    print("True:  ",True) # True:   True
    print(int(True)) # 1

祝好!

更多文章,请关注公众号:编程牧马人

在这里插入图片描述