+-
剑指offer详解(数组)——python
首页 专栏 python 文章详情
0

剑指offer详解(数组)——python

一闪一闪 发布于 1 月 24 日

1.二维数组中的查找

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

思路

类似于二分查找,根据题目,如果拿数组中任意一个元素与目标数值进行比较,如果该元素小于目标数值,那么目标数值一定是在该元素的下方或右方,如果大于目标数值,那么目标数值一定在该元素的上方或者左方。 对于二分查找来说,每次比较只能移动一个指针,在二维数组的查找中,两个指针是一个上下方向移动,一个是左右方向移动。两个指针可以从同一个角出发。 假设我们从左上角出发,也就是row=0 和 col=0,如果元素小于目标数值,我们会将row往下移或着col往右移,这样,被屏蔽的区域可能会是目标元素所在的区域。比如row+=1,那么第一行除左上角以外的元素就被忽略了,如果col+=1,那么第一列出左上角以外的元素就被忽略了。因此这样是不可行的。所以本题从右上角出发寻找解题思路。

代码

# -*- coding:utf-8 -*-
class Solution:
    # array 二维列表
    def Find(self, target, array):
        if array == []:
            return False
        m=len(array)-1
        n=len(array[0])-1
        i,j=0,n #本题的要点是想通这个起点,放在第一行最后一个数字
        while i<=n and j>=0:
            if array[i][j]>target:
                j-=1
            elif array[i][j]<target:
                i+=1
            else:
                return True
        return False

6.旋转数组中的最小数字

一个递增排序的数组做了一次旋转,给你旋转后的数组,找到最小元素。输入{3,4,5,1,2}输出1。
思路
两个方法:1.遍历数组元素,如果前一个元素大于后一个元素,则找到了最小的元素。如果前一个一直小于后一个元素,说明没有旋转,返回第一个元素。

2.二分查找,如果中间元素位于递增元素,那么中间元素>最右边元素,最小元素在后半部分。否则,最小元素在前半部分。

class Solution:
    def minNumberInRotateArray(self, rotateArray):
        if not rotateArray:
            return 0
        minval=rotateArray[0]
        for i in range(len(rotateArray)): # 不能直接 for i in len() 因为int类型需要加range
            if minval>rotateArray[i]:
                minval=rotateArray[i]
        return minval

6.斐波那契数列

现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。

class Solution:
    def Fibonacci(self, n):
        if n<=0:
            return 0
        a=b=1
        for i in range(2,n): # 因为前两个数已经有了,就是1,所以从第三个数开始需要a+b
            a,b=b,a+b # 这里不能写成 a=b   b=a+b,如果写成这样,b就不是前两位相加的值,而是已经被b赋过值的a和b相加的值
        return b

13.调整数组顺序使奇数位于偶数前面

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

# -*- coding:utf-8 -*-
class Solution:
    def reOrderArray(self, array):
        # write code here
        if not array: return []
        adv=[]
        end=[]
        for i in range(len(array)): # 也可以直接写成 for i in array:  则每个数字是 i
            if array[i]%2==0:
                end.append(array[i])
            if array[i]%2==1:
                adv.append(array[i])
        return adv+end # 数组拼接,直接+

19.顺时针打印矩阵

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        if not matrix: return []
        result=[]
        while(matrix):
            result+=matrix.pop(0) # 把第一行取出来
            if not matrix or not matrix[0]:
                break
            matrix=self.turn(matrix) # 把拿掉第一行以后剩余还有数据的矩阵逆时针转90度
        return result
    def turn(self,matrix):
        mid=[]
        for i in range(len(matrix[0])):
            midd=[]
            for j in range(len(matrix)): # 外列内行,用来竖着改造这个矩阵
                midd.append(matrix[j][i])
            mid.append(midd)
        mid.reverse() # 把列表里面的值从当前顺序改变为倒序
        return mid
算法 python 数组
阅读 44 发布于 1 月 24 日
赞 收藏
分享
本作品系原创, 采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议
avatar
一闪一闪
7 声望
1 粉丝
关注作者
0 条评论
得票 时间
提交评论
avatar
一闪一闪
7 声望
1 粉丝
关注作者
宣传栏

1.二维数组中的查找

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

思路

类似于二分查找,根据题目,如果拿数组中任意一个元素与目标数值进行比较,如果该元素小于目标数值,那么目标数值一定是在该元素的下方或右方,如果大于目标数值,那么目标数值一定在该元素的上方或者左方。 对于二分查找来说,每次比较只能移动一个指针,在二维数组的查找中,两个指针是一个上下方向移动,一个是左右方向移动。两个指针可以从同一个角出发。 假设我们从左上角出发,也就是row=0 和 col=0,如果元素小于目标数值,我们会将row往下移或着col往右移,这样,被屏蔽的区域可能会是目标元素所在的区域。比如row+=1,那么第一行除左上角以外的元素就被忽略了,如果col+=1,那么第一列出左上角以外的元素就被忽略了。因此这样是不可行的。所以本题从右上角出发寻找解题思路。

代码

# -*- coding:utf-8 -*-
class Solution:
    # array 二维列表
    def Find(self, target, array):
        if array == []:
            return False
        m=len(array)-1
        n=len(array[0])-1
        i,j=0,n #本题的要点是想通这个起点,放在第一行最后一个数字
        while i<=n and j>=0:
            if array[i][j]>target:
                j-=1
            elif array[i][j]<target:
                i+=1
            else:
                return True
        return False

6.旋转数组中的最小数字

一个递增排序的数组做了一次旋转,给你旋转后的数组,找到最小元素。输入{3,4,5,1,2}输出1。
思路
两个方法:1.遍历数组元素,如果前一个元素大于后一个元素,则找到了最小的元素。如果前一个一直小于后一个元素,说明没有旋转,返回第一个元素。

2.二分查找,如果中间元素位于递增元素,那么中间元素>最右边元素,最小元素在后半部分。否则,最小元素在前半部分。

class Solution:
    def minNumberInRotateArray(self, rotateArray):
        if not rotateArray:
            return 0
        minval=rotateArray[0]
        for i in range(len(rotateArray)): # 不能直接 for i in len() 因为int类型需要加range
            if minval>rotateArray[i]:
                minval=rotateArray[i]
        return minval

6.斐波那契数列

现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。

class Solution:
    def Fibonacci(self, n):
        if n<=0:
            return 0
        a=b=1
        for i in range(2,n): # 因为前两个数已经有了,就是1,所以从第三个数开始需要a+b
            a,b=b,a+b # 这里不能写成 a=b   b=a+b,如果写成这样,b就不是前两位相加的值,而是已经被b赋过值的a和b相加的值
        return b

13.调整数组顺序使奇数位于偶数前面

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

# -*- coding:utf-8 -*-
class Solution:
    def reOrderArray(self, array):
        # write code here
        if not array: return []
        adv=[]
        end=[]
        for i in range(len(array)): # 也可以直接写成 for i in array:  则每个数字是 i
            if array[i]%2==0:
                end.append(array[i])
            if array[i]%2==1:
                adv.append(array[i])
        return adv+end # 数组拼接,直接+

19.顺时针打印矩阵

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        if not matrix: return []
        result=[]
        while(matrix):
            result+=matrix.pop(0) # 把第一行取出来
            if not matrix or not matrix[0]:
                break
            matrix=self.turn(matrix) # 把拿掉第一行以后剩余还有数据的矩阵逆时针转90度
        return result
    def turn(self,matrix):
        mid=[]
        for i in range(len(matrix[0])):
            midd=[]
            for j in range(len(matrix)): # 外列内行,用来竖着改造这个矩阵
                midd.append(matrix[j][i])
            mid.append(midd)
        mid.reverse() # 把列表里面的值从当前顺序改变为倒序
        return mid