"""1、问题描述
将0元素全部移到数组后边,非0元素相对位置不变
"""classremovezero:def__init__(self,nums):
self.num = nums
defrmzeros(self):
nums = self.num
flag =0#这里flag用于记录0的位置for index inrange(len(nums)):if nums[index]!=0:#显然,当没有0元素时,index与flag指示的位置是一致的;而一旦出现0元素,此时index与flag的移动就不一致了,#index会继续后移,而flag则停止后移,此时即记录了0的位置;若下一个元素为0,则只记录第一个位置的0,#若下一个为非0,则交换位置,第一个0移到了0后第一个非0元素的位置;同时,flag更新到第二个0的位置;
nums[flag]= nums[index]if index != flag:
nums[index]=0
flag = flag +1return nums
def__repr__(self):returnrepr(self.num)defrm(self):
nums = self.num
flag =0for index inrange(len(nums)):#这里更直接,与上述方法的区别在于:这里不区别flag与index相等的情况,直接全部交换,而上述则是在不相等时0与非0交换;if nums[index]!=0:
nums[index],nums[flag]= nums[flag],nums[index]
flag = flag +1return nums
nu = removezero([1,0,3,2,0,0,8,9,0])print(nu)print(nu.rm())print(nu.rmzeros())
nzero = removezero([])print(nzero)print(nzero.rm())
"""
4、验证回文串——要求:只比对数字和字母,忽略其余特殊字符,另外空串也是回文串
两大解题思路:
(1)双指针法,逐个进行比较;
(2)借助Python中的特殊API函数,如正则化表达式、如列表生成式等
"""###个人第一次解法:classSolution:defisPalindrome(self, s:str)->bool:#全部转化为小写字母
s = s.lower()
length =len(s)#定义末尾指针
j = length -1#无论是否为数字和字母,长度为0和1,均为回文if(length <=1):returnTrue#进行指针遍历for i inrange(length):#如果左侧指针指向的为非数字字母,此时分两种情况——如果已经与右指针碰到了,说明中间全为非数字字母,就为TRUE;反之,就指针右移if(not s[i].isalnum()):if(i == j):returnTrueelse:continue#如果为字母,就看右指针的指向是否为数字字母,一直移动到指向字母为止;#显然,在左指针已经指向字母的情况下,右指针左移的极限就是左指针当前的位置,#指向的字母相等时,如果右指针等于左指针或者在左指针右侧一位,则为回文;反之,需要移动右指针,进行下一循环判断;#指向的字母不相等,直接判定非回文else:while(not s[j].isalnum()):
j -=1if s[i]== s[j]:if j > i +1:
j -=1continueelse:returnTrueelse:returnFalse##借助python接口函数的快速解法——列表推导式classSolution:defisPalindrome(self, s:str)->bool:
s = s.lower()
s_copy =[e for e in s if e.isalnum()]return s_copy == s_copy[::-1]##借助python的正则化表示库re——sub(pattern,repl,string)classSolution:defisPalindrome(self, s:str)->bool:
s_copy = re.sub("[^a-zA-Z0-9]","",s)
s_copy = s_copy.lower()return s_copy == s_copy[::-1]##官网上比较靠前的代码形式——使用join函数将列表推导式筛选后的结果重新连成字符串classSolution:defisPalindrome(self, s:str)->bool:
s_copy ="".join(e.lower()for e in s if e.isalnum())return s_copy == s_copy[::-1]##官网上比较靠前的代码形式——使用filter()函数配合join()函数,本质上与上述没有区别,但filter比推导式更快classSolution:defisPalindrome(self, s:str)->bool:
s_copy ="".join(filter(str.isalnum,s)).lower()return s_copy == s_copy[::-1]###双指针法的参考写法"""
(1)设置一个头指针和一个尾指针
(2)头指针从头开始找,找到第一个数字或字符
(3)尾指针从尾开始找,找到最后一个数字或字符
(4)比较两者是否相同,不同就return False
(5)相同则两指针往中间靠(关注指针的位置更新)
(6)当 i > j 的时候,return True
"""classSolution:defisPalindrome(self, s:str)->bool:
i, j =0,len(s)-1while i < j:while i <len(s)andnot s[i].isalnum():
i +=1while j >-1andnot s[j].isalnum():
j -=1if i > j:returnTrueif s[i].upper()!= s[j].upper():returnFalseelse:
i +=1
j -=1returnTrue
"""
5、区间最大和求解
题目要求:
给定n个正整数组成的数列以及一个数M,要求在这n个正整数中寻找一个区间[i,j](即数列的第i个元素到第j个元素),这个区间和要是小于M的最大和;
如果有多个这样的区间和(即小于M的最大和区间不唯一),则返回i值最小的区间
这个题的目的,是逐步推导优化时间复杂度从O(N^3)、O(N^2)、O(NlogN)、O(N);
示例:
输入:5 10
2 3 4 5 6
输出:1 3 9
#即表示数组5个数字,M = 10,第1个到第3个的区间和最大,和为9
"""# 从控制台键盘输入尝试#x = input("please input numbers:").split(sep = " ")#x_int = [int(e) for e in x if len(e) != 0]
n =5
M =10
nums =[2,3,4,5,6]### (1)最直接,最暴力的解法——逐个遍历,这样会有两重循环,使用了python中的求和sum函数,相当于逐个遍历一遍元素,又一重循环definterval_Sum_max(n,M,nums):#n为数组长度,M为指定的最大数字,nums为数组
interval_i =0
interval_j =0
interval_sum =0
temp_sum =0for i inrange(n):for j inrange(i +1, n +1):
temp_sum =sum(nums[i:j])print("sum of [{i},{j}] = {sum}".format(i = i+1, j = j,sum=temp_sum))#这里调试需要注意的是,为什么要j-1,因为num[i,j]的求和,实际上是对第i个到第(j-1)个元素进行求和的#同时,注意到第二层循环是i+1 到 n+1,也是考虑到了进行nums[i,j]切片时,如果j按照最后一个元素的位置索引(n-1)的话,是无法对最后一个#元素求和的if temp_sum > interval_sum and temp_sum <= M:#这里为什么要给i+1,而给j保持原样呢?——这就是因为python索引从0开始,所以区间左端的索引加1才对呀实际的第几个元素#而j保持原样,则就是因为pyhon进行切片时[i,j]实际上只提取到索引的j-1元素,而恰恰对应了实际索引的第j个元素,所以不用变#这里对区间内符合要求的求和进行不断更新
interval_i = i +1
interval_j = j
interval_sum = temp_sum
return[interval_i,interval_j,interval_sum]
interval_Sum_max(n,M,nums)###(2)
sum of [1,1] = 2
sum of [1,2] = 5
sum of [1,3] = 9
sum of [1,4] = 14
sum of [1,5] = 20
sum of [2,2] = 3
sum of [2,3] = 7
sum of [2,4] = 12
sum of [2,5] = 18
sum of [3,3] = 4
sum of [3,4] = 9
sum of [3,5] = 15
sum of [4,4] = 5
sum of [4,5] = 11
sum of [5,5] = 6
[1, 3, 9]
"""1、问题描述 将0元素全部移到数组后边,非0元素相对位置不变"""class removezero: def __init__(self,nums): self.num = nums def rmzeros(self): nums = self.num flag = 0 #这里flag用于记录0的位置 for index in range(len(nums)): if nums[inde