Python编程

本文探讨了Python编程在解决剑指offer问题和在线编程挑战(OJ)中的应用,涵盖全排列、斐波那契数列、最大连续子序列等算法,并涉及字符串、列表操作和链表处理。同时讲解了二维数组遍历和字符串内置函数的使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

剑指offer

1. 全排列

题目描述

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

示例1

输入

[3,32,321]

返回值

"321323"
# -*- coding:utf-8 -*-
"""
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,
打印能拼接出的所有数字中最小的一个
"""
import itertools   #使用模块产生可迭代对象
class Solution(object):
    def PrintMinNumber(self, numbers):
        # write code here
        assert len(numbers)>0 #
        lis = []
        for l in list(itertools.permutations(numbers)):#全排列迭代成元组
            str0 = [str(i) for i in l] #l为元组类型转换成字符列表str0
            l = ''.join(str0) #将字符数字连接成整体字符串
            lis.append(int(l))#将字符l转换成整型存入到lis列表中
        return min(lis)#返回lis列表中的最小值
    
    
# -*- coding:utf-8 -*-
import itertools
class Solution:
    def PrintMinNumber(self, numbers):
        if len(numbers)==0:
            return ""
        if len(numbers)==1:
            return numbers[0]
        res=[]
        for i in numbers:
            res.append(str(i))
        temp = list(set(map("".join, itertools.permutations(res))))
        return str(min(temp))
    

join():连接字符串数组。将字符串、元组、列表中的元素以指定的字符(分隔符)连接生成一个新的字符串

map(function, iterable, ...)会根据提供的函数对指定序列做映射。第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。

2. 斐波那契数列

斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)

0、1、2、3、5、8、

#1、递归方法,python调试过程中速度太慢没有通过
class Solution:
    def Fibonacci(self,n):
        if n<=1:
            return n
        else:
            return self.Fibonacci(n-1)+self.Fibonacci(n-2)
#2、利用for循环语句与数列的方法进行运算,将数列加入列表中,并对最后一个元素进行返回。
class Solution:
    def Fibonacci(self, n):
        num = []
        for i in range(n+1): #最后1个数字不包含
            if i == 0:
                num.append(0)
            elif i == 1:
                num.append(1)
            else:
                num.append(num[-1]+num[-2])
        return num[-1] #list[-1]表示最后一个元素,list[-2]表示倒数第二个元素

3. 最大连续子序列

输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为 O(n).

示例1

输入:

[1,-2,3,10,-4,7,2,-5]

复制

返回值:

18
输入的数组为{1,-2,3,10,-4,7,2,-5},和最大的子数组为{3,10,-4,7,2},因此输出为该子数组的和 18。 
设dp[i]为以下标i元素结尾的最大和
递推式:dp[i]=max(dp[i-1]+array[i],array[i])
初始状态 dp[0]=array[0]
思路就是:如果该元素之前的最大和加上当前元素值 小于 当前元素,那就从当前元素重新开始计算,否则按两者加和作为此处的最大和。
最后得到的dp数组中最大的那一个,就是答案。

class Solution:
    def FindGreatestSumOfSubArray(self, array):
        # write code here
        dp = [0]*len(array)
        dp[0] = array[0]
        #或直接拷贝一份:dp = array[:],修改dp不会修改array
        for i in range(1,len(array)): #因为有i-1,所以要从1开始循环
            dp[i] = max(dp[i-1] + array[i], array[i])
        return max(dp)

4. 跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

f(0)=0,f(1) = 1, f(2) = 2, f(3) = 3, f(4) = 5… 可以总结出f(n) =f(n-1) +f(n-2)的规律

class Solution:
    def jumpFloor(self, number):
        # write code here
        num = []
        for i in range(number+1): #最后1个数字不包含
            if i == 0:
                num.append(0)
            elif i == 1:
                num.append(1)
            elif i == 2:
                num.append(2)
            else:
                num.append(num[-1]+num[-2])
        return num[-1] #list[-1]表示最后一个元素,list[-2]表示倒数第二个元素

5. 二维数组遍历

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

[

[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]

]

给定 target = 7,返回 true。

给定 target = 3,返回 false。

class Solution:
    # array 二维列表
    def Find(self, target, array):
        # write code here
        for i in array:
            if target in i:
                return True
        return False

6. 字符串内置函数

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

class Solution:
    def replaceSpace(self , s ):
        # write code here
        arr = s.split(" ")  # 字符串转列表,以" "分开,split传参分割符
        res = ("%20").join(arr) # 列表转字符串,元素之间以"%20"连接,join传参列表
        res1 = str(res) # str函数将参数转化为字符串
        return res1
class Solution:
    def replaceSpace(self , s ):
        # write code here
        return s.replace(' ','%20')

7. 链表

输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

输入:

{67,0,24,58}

返回值:

[58,24,0,67]
class Solution:
    # 返回从尾部到头部的列表值序列,例如[1,2,3]
    def printListFromTailToHead(self, listNode):
        if not listNode:
            return []
        stack = [] 
        while listNode: # 遍历链表
            stack.append(listNode.val)  # 获取链表当前节点的 value 值,val即可获取
            listNode = listNode.next    # 当前节点向后移动
        return stack[::-1] # 列表的切片操作,前两个参数是截取范围,缺省表示全长截取,第三个参数1表示正向,-1表示反向

OJ

1. 输入输出

两行输入:

# 第一行输入两个整数
# 第二行输入多个整数
def func():
    a, b = map(int, input().strip().split())
    l = input().strip().split()
    
if __name__ == "__main__":
    func()
# 第一行输入1个整数
# 第二行输入多个整数
# 输出多个整数
def func():
    n = int(input())
    arr = list(map(int, input().split(" ")))
    
    print("%d %d %d" % (a, b, c))
if __name__ == "__main__":
    func()

多行输入(每行输入一个整数,输入到文件末尾结束*):

# 多行整数
def func():
    while True:
         try:
            n = int(input())
            print(res)
    	except EOFError:
        	break
        
if __name__ == "__main__":
    func()

2. 硬币分法

在一个国家仅有1分、2分、3分硬币,将n块钱兑换成硬币,共有多少种分法。

#!/usr/bin/python3
# n = x + 2y +3z ,也就是求给定n值的情况下,x,y,z的组合有多少种
def func():
    while True:
        try:
            n = int(input())
            coin3 = n//3 # 先确定3分钱的个数,最多有coin3个三分钱硬币,3分钱硬币共有coin3种分法
            res = 0
            for i in range(coin3+1): 
                res = res + (n - 3*i)//2 + 1 # 剩余的钱多能有coin2=(n-3*i)//2个两分钱硬币,2分钱硬币共有coin2中分法,最后加上全是1分钱硬币的情况,1分钱的分法在3分钱和2分钱确定之后自动确定,只有唯一解
            print(res)
        except (ValueError, EOFError):
            break
        
if __name__ == "__main__":
    func()

python 中 // 和 int(a/b)的区别:

print(13/2)  # 6.5
print(13//2)  # 6
print(int(6.5))  # 6

print(-13/2)  # -6.5
print(-13//2)  # -7
print(int(-6.5))  # -6
"""
整除号://
整除运算,结果向负无穷方向去,取最近的整数

浮点数除法:/
返回float型

使用强制类型转换取整数:int()
结果向0靠近,取最近的整数
"""

3. 逆序对

若i<j,A[i]>A[j],则称A[i]、A[j]为一对逆序对

输入:

第一行输入一个正整数,表示数列A的个数

从第二行起的n行,每行按顺序输入数列A的1个元素

def func():
    n = int(input())
    arr = []
    cnt = 0
    for _ in range(n):
        arr.append(int(input()))
    for i in range(n):
        for j in range(i+1,n):
            if int(arr[i]) > int(arr[j]):
                cnt = cnt +1
    print(cnt)
if __name__ == "__main__":
    func()

4. 升级加薪(区间覆盖问题)

H公司共有n个员工,每个人都有唯一的编号(从1到n),升级形式:在[l, r]区间内的所有员工升一级。每个员工刚入职都是0级。在一年之中H公司共进行了m此升级。请计算出一年每位员工的级别。

输入:

第一行有两个整数,n和m

接下来m行,每行包含两个整数l和r,表示编号在l和r之前的所有员工升一级。

输出:

n个整数,表示员工的级别

样例:

输入

3 2

1 3

2 3

输出:

1 2 2

def func():
    n, m = (int(i) for i in input().split())
    arr = [0] * (n+2)
    for i in range(m):
        l, r = (int(i), for i in input().split())
        arr[l-1] += 1
        arr[r] -= 1
    t = 0
    l = []
    for i in range(n):
        t += arr[i]
        l.append(str(t))
    print(" ".join(l))
if __name__ == "__main__":
    func()

####
a = [1,2,3]
print(" ".join(str(i) for i in a))  # 输出整数列表,元素之间加空格

字符串和列表

列表转字符串列表、整数

list1 = [1, 2, 3]
str1 = "".join([str(i) for i in list1])
num1 = int(str1)
print(isinstance(num1, int))
>>>
True

字符串转列表

str1 = "a, b, c"
list1 = str1.split(",")
print(list1)
>>>
['a', ' b', ' c']

字符串和列表反转

a = 'i lova u'
b = a[::-1]
print(b)
>>> u avol i
a = ["i","love","u"]
b = a[::-1]
print(b)
>> ['u', 'love', 'i']

1. 字符串

https://blog.youkuaiyun.com/qq_39241986/article/details/107805010

# str.capitalize()、str.upper()、str.lower()、str.swapcase()、str.title()
# str.capitalize()将字符串的第一个字母变成大写,其他字母变小写。
str1 = "python go go go"
str2 = str1.capitalize()
print(str2)
>>> Python go go go
# str.upper()将字符串中的小写字母转为大写字母。
str1 = "python go go go"
str2 = str1.upper()
print(str2)
>>> PYTHON GO GO GO
# str.lower()转换字符串中所有大写字符为小写。
# str.swapcase()对字符串的大小写字母进行转换,小写变大写,大写变小写。
# str.title()返回"标题化"的字符串,所有单词的首个字母转化为大写,其余字母均为小写。
str1 = "python go go go"
str2 = str1.title()
print(str2)
>>> Python Go Go Go

# str.count(sub, start, end) 统计字符串里某个字符出现的次数。可选参数为在字符串搜索的开始与结束位置。
# start, end遵循**“左闭右开”**原则。
str1 = "banana"
sum1 = str1.count('a')
print(sum1)
>>> 3
# str.endswith(suffix, start, end)和str.startswith(substr, beg, end) 判断字符串是否以指定后缀结尾/开头,如果以指定后缀「结尾」/「开头」返回 True,否则返回 False。
# start, end遵循**“左闭右开”**原则。
str1 = 'Hello World!'
bool1 = str1.endswith('!')
bool2 = str1.startswith('H')
print(bool1,bool2)
>>> True True

# str.find(str, beg, end)和str.index(str, beg, end) 检测字符串中是否包含子字符串 str ,如果指定范围内如果包含指定索引值,返回的是索引值在字符串中的起始位置。如果不包含索引值,str.find()返回-1,str.index()报错
str0 = 'Hello World!'
index = str0.find('e')
print(index)
>>> 1

# str.isalnum()、str.isalpha()、str.isdigit()、str.isnumeric()、str.islower()、str.isspace()、str.istitle()、str.isupper()
# str.isalnum()检测字符串是否由字母和数字组成。
# str.isalpha()检测字符串是否只由字母或文字组成。
# str.isdigit()检测字符串是否只由数字组成。「True:」 Unicode数字,byte数字(单字节),全角数字(双字节)「False:」 汉字数字,罗马数字,小数
# str.isnumeric()检测字符串是否只由数字组成。「True:」 Unicode 数字,全角数字(双字节),汉字数字「False:」 小数,罗马数字
# str.islower()检测字符串是否由小写字母组成。
# str.isspace()检测字符串是否只由空白字符组成。
# str.istitle()检测字符串中所有的单词拼写首字母是否为大写,且其他字母为小写。
# str.isupper()检测字符串中所有的字母是否都为大写。

# str.join()将序列中的元素以指定的字符连接生成一个新的字符串。
s1 = "-"
s2 = ""
seq = ("r", "u", "n", "o", "o", "b") # 字符串序列
print (s1.join( seq ))
print (s2.join( seq ))
>>> r-u-n-o-o-b
runoob

# len() 返回对象(字符、列表、元组等)长度或项目个数。

# str.lstrip()、str.rstrip()、str.strip() 截掉字符串「左边」/「右边」/「左右」两侧的空格或指定字符。

str0 = '    Hello World!'
str0.lstrip()
>>> 'Hello World!'
str1 = 'aaaa    Hello World!'
str1.lstrip('a')
>>> '    Hello World!'

# find() 
#find函数(查找and是否在string_example字符串中)
string_example = "hello world itheima and itheimaApp"
index = string_example.find("and")
print(index)
#若未找到则返回-1
index1 = string_example.find("ans")
print(index1)
>> 20
-1

# str.replace(old, new, max)
# old -- 将被替换的子字符串。
# new -- 新字符串,用于替换old子字符串。
# max -- 可选字符串, 替换不超过 max 次
#replace函数把字符串中的old(旧的字符串)替换成new(新的字符串)
old_string = "hello world world itheima world and itheimaApp"
#参数说明:world:需要被替换掉的字符串;worlds:将world换成worlds;2:需要被替换的次数不超过2次
new_string =old_string.replace("world","worlds",2)
>>> hello worlds worlds itheima world and itheimaApp

# str.rfind(str, beg, end)和str.rindex(str, beg, end)
str.rfind()返回字符串最后一次出现的位置,如果没有匹配项则返回-1str.rindex()返回字符串最后一次出现的位置,如果没有匹配的字符串会报异常。


# str.split(str, num)
# str -- 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
# num -- 分割次数。默认为 -1, 即分隔所有。
txt = "print#hello#world#!"
txt.split("#")
>>> ['print', 'hello', 'world', '!']

2. 列表切片

https://www.cnblogs.com/xuchunlin/p/6045282.html

https://blog.youkuaiyun.com/weixin_43970977/article/details/88032412

https://www.cnblogs.com/twelvezuo/p/12068902.html

# len()
li = [1,2,3,4,5,6,7]
len1 = len(li)
print(len1)
>>> 7
# min()
li = [-1,1,2,3,4,5,6,7]
len1 = min(li)
print(len1)
>>> -1
# max()
li = [-1,1,2,3,4,5,6,7]
len1 = max(li)
print(len1)
>>> 7
# sum()
li = [-1,1,2,3,4,5,6,7]
len1 = sum(li)
print(len1)
>>> 27
# count()
list1 = [1,1,2,3,4,5,5,5]
count = list1.count(5)
print(count)
>>> 3
# append()
list1 = [1,1,2,3,4,5,5,5]
list1.append("a")
print(list1)
>>> [1, 1, 2, 3, 4, 5, 5, 5, 'a']
# 注意 append()和extend()的区别
list1 = [1,1,2,3,4,5,5,5]
list2 = ["a","b","c"]
list1.append(list2)
print(list1)
>>> [1, 1, 2, 3, 4, 5, 5, 5, ['a', 'b', 'c']]
# extend()
list1 = [1,1,2,3,4,5,5,5]
list2 = ["a","b","c"]
list1.extend(list2)
print(list1)
>>> [1, 1, 2, 3, 4, 5, 5, 5, 'a', 'b', 'c']
# index() 函数用于从列表中找出某个值第一个匹配项的索引位置。
list1 = [1,1,2,3,4,5,5,5]
index = list1.index(5)
print(index)
>>> 5
# insert()
list1 = [1,1,2,3,4,5,5,5]
list1.insert(2,"a")
print(list1)
>>> [1, 1, 'a', 2, 3, 4, 5, 5, 5]
# pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。可以指定弹出某个元素。该方法返回从列表中移除的元素对象。
list1 = [1,1,"a",3,4,5,5,5]
pop = list1.pop(2)
print(list1)
print(pop)
>>> [1, 1, 3, 4, 5, 5, 5]
>>> a
list1 = [1,1,"a",3,4,5,5,5]
list1.pop(2)
print(list1)
>>> [1, 1, 3, 4, 5, 5, 5]
# remove() 函数用于移除列表中某个值的第一个匹配项。
list1 = [1,1,"a",3,4,5,5,5]
list1.remove(5)
print(list1)
>>> [1, 1, 'a', 3, 4, 5, 5]
# reverse() 函数用于反向列表中元素。
list1 = [1,1,"a",3,4,5,5,5]
list1.reverse()
print(list1)
>>> [5, 5, 5, 4, 3, 'a', 1, 1]
# sort() 函数用于对原列表进行排序,如果指定参数,则使用比较函数指定的比较函数。
# list.sort( key=None, reverse=False)参数:
#key:主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。reverse:排序规则,reverse = True降序,reverse = False升序(默认)。
list1 = [1,1,6,3,4,5,5,5]
list1.sort()
print(list1)
>>> [1, 1, 3, 4, 5, 5, 5, 6]
list1 = [1,1,6,3,4,5,5,5]
list1.sort(reverse=True)
print(list1)
>>> [6, 5, 5, 5, 4, 3, 1, 1]
# clear() 函数用于清空列表。
list1 = [1,1,6,3,4,5,5,5]
list1.clear()
print(list1)
>>> []
# copy() 函数用于复制列表。
list1 = [1,1,6,3,4,5,5,5]
list2 = list1.copy()
print(list2)
>>> [1, 1, 6, 3, 4, 5, 5, 5]
# 列表切片
li = [1,2,3,4,5,6,7]
print(li[1:])   #输出[2,3,4,5,6,7],省略终止索引,表示取起始索引之后的所有值,等效于li[1:len(li)]
print(li[:3])   #输出[1,2,3],省略起始索引,表示从0开始取,等效于li[0:3]
print(li[:])    #输出[1,2,3,4,5,6,7],省略起始索引、终止索引、步长值表示取全部,等效于li[0:len(li):1]
print(li[::])   #输出[1,2,3,4,5,6,7],省略起始索引、终止索引、步长值表示取全部,等效于li[0:len(li):1]
print(li[::-1]) #输出[7,6,5,4,3,2,1],省略起始索引、终止索引,步长值为-1,表示反向获取
>>>
[2, 3, 4, 5, 6, 7]
[1, 2, 3]
[1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7]
[7, 6, 5, 4, 3, 2, 1]


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值