10道Python小白练手题(习题详解,代码分析)赶紧收藏!

目录

题目一:两数之和

题目二:回文数

题目三:杨辉三角

题目四: 罗马数字转整数

题目五:字符串的分数

题目六:最长公共前缀

题目七:有效的括号

题目八:删除有序数组中的重复项

题目九:移除元素

题目十:找出字符串中第一个匹配项的下标


题目一:两数之和

给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。
你可以按任意顺序返回答案。

提取题目中关键要求:

1.返回两个下标,且不能使用两次相同的元素;

2.target是数组中两数之和;

3.要遍历数组中所有的数

根据题目要求:设定两个未知数(i,j)且i不等于j,target=nums[i]+nums[j],采用for循环查找

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        for i in range(len(nums)):
            for j in range(i+1,len(nums)):  #嵌套for循环,遍历数组中的每一个数,并且i不能等于j
                if target==nums[i]+nums[j]:  #如果符合题目要求(这里注意if要用比较运算符==)
                    return[i,j]              #就输出结果

题目二:回文数

给你一个整数,如果是一个回文整数,返回true;否则,返回false。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
例如,121是回文,而123不是。 

涉及知识点:python 反向输出字符串

首先,我们要知道字符串从右到左是怎么输出的

x="hello"
print(x[-1])  #输出o
print(x[1])   #输出e

由这一小段代码,我们可以知道,字符串从左到右的下标是0,1,2,3......而从右往左的下标则是-1,-2,-3......接下来我们就可以开始学习切片:

x="hello"
print(x[::-1])  #输出olleh,从下标-1开始,一直往前取到开头,就是将整个字符串倒过来
print(x[2::])   #输出llo,从下标2开始,一直往后取到结尾
print(x[1:5])   #输出ello,注意包前不包后
print(x[0:-1])  #输出hell,注意包前不包后

现在我们再来看题目,x是一个整型,我们要把它变为字符串才能进行切片,并且输出布尔型。

class Solution:
    def isPalindrome(self, x: int) -> bool:
        a=list(str(x))     #将x整型变为字符串并赋给a
        if a[::-1]==a:     #a[::-1]将字符串从右到左表示,如果与原来的字符串相等,那么就为回文数
            return True
        else:
            return False   #注意布尔型的写法:True和False

题目三:杨辉三角

给定一个非负整数numRows,生成「杨辉三角」的前numRows行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。

把杨辉三角的每一排左对齐:

 由图可以知道,有行有列,那么我们就可以设一个二维数组c[i][j],计算方式如下:
1.每一排的第一个数和最后一个数都是1,即c[i][0]=c[i][i]=1。
2.其余数字,等于左上方的数,加上正上方的数,即c[i][j]=c[i-1][j]+c[i-1][j-1]。例如4=1+3,6=3+3等

class Solution:
    def generate(self, numRows: int) -> List[List[int]]:
        c = [[1] * (i + 1) for i in range(numRows)]      #输出格式,并且先输出为1
        for i in range(2, numRows):
            for j in range(1, i):
                c[i][j] = c[i - 1][j - 1] + c[i - 1][j]  # 左上方的数 + 正上方的数
        return c

拓展:打印杨辉三角

# 杨辉三角
c=[1]
for i in range(10):
    print(c)
    c.append(0)    #添加0,输出三角形样式
    c=[c[k]+c[k-1] for k in range(i+2)]

题目四: 罗马数字转整数

 

首先,通过观察我们可以知道,我们首先要将数值赋给每一个字母,所以可以采用字典(dic)

1.观察示例1,我们知道相同的字母会相加。

2.通过观察示例2-3我们发现,V>I,X>I,右边大于左边,这时候是相减。

3.再看示例4,“L>V”,“V>I",左边大于右边,这时候是相加。

结合以上规律总结:当”右边大于左边“时是相减,”左边大于右边“时相加,”相同“也是相加,通过示例5可以验证我们总结的规律是对的。

class Solution:
    def romanToInt(self, s: str) -> int:
        #设定一个字典
        dic = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}  
        ans = 0           #将计算结果保存在ans中
        n = len(s)
        for i in range(n):
            if i < n-1 and dic[s[i]] < dic[s[i+1]]:   #当右边大于左边时
                ans -= dic[s[i]]                      #相加
            else:
                ans += dic[s[i]]        #其余时候相加
        return ans

题目五:字符串的分数

给你一个字符串s,一个字符串的分数定义为相邻字符ASCII码差值绝对值的和

请你返回s的分数。

涉及知识点:求和,绝对值,ASCII的实现,循环

在 Python 中,可以使用内置函数 ord()来实现 ASCII 码和字符之间的转换。 将字符转为 ASCII 码,可以使用 ord() 函数。它返回给定字符的 ASCII 码值:

a="A,B"
c=ord(a[0])
print(c)      #输出65

绝对值abs,用法如下:

a="A,B"
b=ord(a[1])
d=ord(a[0])
c=abs(ord(a[1])-ord(a[0]))
print(b)      #输出44
print(d)      #输出65
print(c)      #输出21,|44-65|

再将他们求和并输出,就能得出答案:

方法一:

class Solution:
    def scoreOfString(self, s: str) -> int:
         return sum(abs(ord(s[i]) - ord(s[i - 1]))
         for i in range(1, len(s)))

方法二:

class Solution:
    def scoreOfString(self, s: str) -> int:
        sum=0
        for i in range(1, len(s)):
            sum+=abs(ord(s[i])-ord(s[i-1]))
            i+=1
        return sum

题目六:最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串

思路:

我们假设第一个字符串A为前缀,如果A串与B串字符不同,则去掉A串最后一个字符与B串重新匹配。当A串完全匹配B串时,就说明此时输出的是A串与B串的公共前缀。

在python中,s = s[:-1]用于去掉最后一个字符。实现如下:

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if len(strs) == 0:
            return ''    #当strs中没有字符串时,A串就不能被定义,所以直接输出''
        s = strs[0]      #设s为第一个字符串,也就是A串
        for i in range(1, len(strs)):  #每一个字符串都要与A串进行对比
            while strs[i].find(s) != 0 :   #如果B串与A串不相等
                s = s[:-1]                 #就将A串最后一个字母删去
        return s

题目七:有效的括号

给定一个只包括'('')''{''}''['']'的字符串,判断字符串是否有效。
有效字符串需满足:
1.左括号必须用相同类型的右括号闭合。
2.左括号必须以正确的顺序闭合。
3.每个右括号都有一个对应的相同类型的左括号。

根据示例我们可以发现,如果括号是一对一对的则输出true,如果有单的则输出false,那我们换一种思维,如果将一对的括号,变为相同的括号,判断一不一样,若一样则消除。

以 s={[()]} 为例说明:

创建一个空栈st。
从左到右遍历 s。
s[0]={,这是一个左括号,入栈。
s[1]=[,这是一个左括号,入栈。
s[2]=(,这是一个左括号,入栈。
s[3]=),这是一个右括号,它必须和栈顶的 ( 组成一对(消除),弹出栈顶。
s[4]=],这是一个右括号,它必须和栈顶的 [ 组成一对(消除),弹出栈顶。
s[5]=},这是一个右括号,它必须和栈顶的 { 组成一对(消除),弹出栈顶。
遍历结束,由于栈为空,说明所有括号均已匹配完毕,返回 true。反之,如果在遍历的过程中,发现栈为空,或者括号类型不匹配的情况,返回 false。此外,如果遍历结束栈不为空,说明还有没匹配的左括号,返回 false。

class Solution:
    def isValid(self, s: str) -> bool:
        if len(s) % 2 ==1:
            return False     #如果s为奇数,那么括号肯定不是一对一对的,所以输出False
    #定义字典,将右括号变为左括号
        dic = {
            ')': '(',
            ']': '[',
            '}': '{'
        }
        st=[]            #设置一个空的栈
        for i in s:      #进入循环
            if i not in dic:       #如果i不是为右括号
                st.append(i)       #那么就将i入栈
            elif not st or st.pop() != dic[i]:      #如果栈里面的括号与左括号不匹配
                return False                        #则输出False
        return not st   #not st:如果stack为空,not stack则不为空,判定为True。如果stack不为 
                         空,则not stack为空,判定为False。

题目八:删除有序数组中的重复项

给你一个非严格递增排列的数组nums,请你原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。元素的相对顺序应该保持一致。然后返回nums中唯一元素的个数。
考虑nums的唯一元素的数量为K,你需要做以下事情确保你的题解可以被通过:
1.更改数组nums,使nums的前个元素包含唯一元素,并按照它们最初在nums中出现的顺序排列。nums的其余元素与nums的大小不重要。
2.返回k

 通过观察示例,我们可以发现,当nums[i]=nums[i-1]时,数字将被删除,当nums[i]!=nums[i-1]时,数字将被保留。同时可以发现k=不重复的个数

我们将示例2罗列出来,以便同学们更好的理解:

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        k=1
        for i in range(1,len(nums)):   
            if nums[i] != nums[i-1]:    #如果nums[i] != nums[i-1],将被保留
                nums[k] =nums[i]        #将数字赋给k
                k+=1      
        return k

题目九:移除元素

给你一个数组nums和一个值val,你需要原地移除所有数值等于val的元素。元素的顺序可能发生改变。然后返回 nums中与val不同的元素的数量。
假设nums中不等于val的元素数量为,要通过此题,您需要执行以下操作:
1.更改nums数组,使nums的前k个元素包含不等于val的元素。nums的其余元素和nums的大小并不重要。
2.返回K

本题与题目八很类似,本题主要是要将数组中和val的值相等的数删掉,那么就可以表示为:

if nums[i]=val:就删除,反过来则是,if nums[i]!=val:就保留。根据题目八的代码我们可以知道保留怎么写。注意在本题中nums可能为空,这时k返回0:

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        k=0
        for i in range(len(nums)):
            if nums[i]!=val:             #如果没有和val一样的数,则保留
                nums[k]=nums[i]          #将数值保留在nums[k]中
                k+=1
        return k

题目十:找出字符串中第一个匹配项的下标

给你两个字符串haystack和needle,请你在haystack字符串中找出needle字符串的第一个匹配项的下标(下标从0开始)。如果needle不是haystack的一部分,则返回-1

 

通过题目,我们可以知道输出的时下标,所以设i,j两个数,来分别遍历这两个字符串。

BF算法思想:对于给定文本串与模式串,从文本串的第一个字符开始与模式串的第一个字符进行比较,如果相等,则继续逐个比较后续字符,否则从文本串的第二个字符起重新和模式串进行比较。依次类推,直到模式串中每个字符依次与文本串的一个连续子串相等,则模式匹配成功。否则模式匹配失败。
具体步骤如下:
1.对于给定的文本串与模式串p,求出文本串的长度为n,模式串p的长度为m。
2.同时遍历文本串和模式串,先将T[0]与p[0]进行比较。
a.如果相等,则继续比较T[1]和p[1]。以此类推,一直到模式串的末尾p[m-1]为止。
b.如果不相等,则将文本串移动到上次匹配开始位置的下一个字符位置,模式串则回退到开始位置,再依次进行比较。
3.当遍历完文本串或者模式串的时候停止搜索。

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        i = 0
        j = 0         #定义i,j用来储存下标
        len1 = len(haystack)
        len2 = len(needle)

        while i < len1 and j < len2:   #定义范围
            if haystack[i] == needle[j]:   #如果两个字符相等,则开始进行下一个字符的对比
                i += 1
                j += 1   
            else:
                i = i - (j - 1)         #如果不相等,则开始从原来的地方+1运行
                j = 0

        if j == len2:               #如果j等于len2,说明所有数字全都已经遍历完毕
            return i - j            
        else:
            return -1               #如果没有遍历完,则没有匹配

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值