python实现字符串和整数之间算法问题

python实现

一、字符串转成整数

开头可能是空格、’+’、’-’、‘数字’、‘字母’,

但是遇到字母字符就要停止,或者开头是‘±’也要停止。

还要注意溢出问题;对于空格允许多个所以可以用循环跑完,也可以直接使用字符串方法strip()

def strToint(s):
	if not s:
		return 0
	max_num, min_num = 2**31 - 1, -2**31
	length = len(s)
	# 为获取字符里对应数字
	char_num = ['0','1','2','3','4','5','6','7','8','9']
	# 用来判断正负
	sign = ['+','-']
	flag = 1
	i = 0
	while s[i] == ' ':
		i += 1
		if i == length:
			return 
	if s[i] in sign:
		if s[i] == '-':
			flag = -1
	# 用来记录返回的整数
	ret = 0
	for j  in range(i,length):
		if s[j] in char_num:
			# 判断是否溢出 这个地方ret只是正数
			if ret > max_num // 10 or (ret == max_num and s[j] > '7'):
				return max_num if flag == 1 else min_num
				# 索引和其值正好对应,并且还是int型
			ret = ret*10 + char_num.index(s[j])
		#因为前面的情况都已经判断结束(从i开始的),一旦遇到不是数字,直接跳出
		else:
			break
	return ret*flag
			

二、反转整数

实现起来很简单,思路就是求余获取整数的每一位,然后循环按照十进制加法反转,但是需要注意几点1、参数的正负值;2、溢出返回0

def convert(x):
	flag = 1
	if x < 0:
		x = -x
		flag = -1
	ret = 0
	max_num, min_num = 2**31 - 1, -2**31
	while x:
		num =  x % 10
		x = x // 10
		if ret > max_num //10 or (ret == max_num // 10 and num > 7):
			return 0
		ret = ret * 10 + num
	return ret*flag
		

三、字符串Z型排列打印

问题:字符串s按照上下指定numRow行这样Z型排列,要求按照每行从左到

右读取;

首先可以看做是两层循环,因为有numRow行,所以外层相当于循环

numRow次,每次增加1,内部循环首先循环次数是和字符换长度有关,每次

起始位置是和行数有关的,其次就是要判断每行相邻的两个数之间的间距即循环变量步长。

主要针对两个数距离问题分析:不难发现首尾两行两数A和B之间相隔的数有 2numRow - 3 个,
但是其他行对于相距 2
numRow - 3 个数里面还有一个数C,这个C与B之间间隔可以通过行数知道2*i -1,i= 1,…,numRow。(i=0不需要这样算)

def charZprint(s,numRow):
	if not s:
		return 
	res = ''
	# 之间间隔数是 2*numRow - 3 ,但是获得后面那个数索引需要再加1
	gap = 2*numRow - 2
	n = len(s)
	for i in range(numRow):
		j = 0
		while j + i < n :
			ret += s[j+i]
			# 获取C的索引 gap - 2*i  + j + i (j+i是起始,gap - 2*i 间隔+1)
			if i != 0 and i !=  numRow -1 and gap + j - i < n:
				ret += s[gap + j - i]
		j += gap
	return ret
				
	

四、回文子串

一个回文子串去掉首尾字符仍然是回文子串,这样我们就是以长度为1或2两左右扩展并记录对应长度,最终返回最长子串。

def longest_str(s):
	if not s:
		return 0
	n = len(s)
	start, end = 0, 0
	def find(left,right):
		while left >=0  and right < n  and s[left] == s[right]:
			left -= 1
			right += 1
		return left + 1, right - 1 
	for i in range(n):
		#  下面相当于分别以长度为12为扩展
		left1, right1 = find(i,i)
		left2, right2 = find(i,i+1)
		if right1 - left1 > end - start:
			start, end = left1, right1
		if right2 - left2 > end - start:
			start, end = left2, right2
	return s[startL:end+1]

五、两个有序数组的中位数

思路1:两个有序数组使用一次归并排序,合并数组长度L若是偶数,则第L//2个数和第L//2+1

个数平均值即为所求中位数,若是奇数,则第(L+1)//2个数是中位数。

思路2:二分查找;L为偶数时,假设第k小的数为中位数,第一个数组array1的长度为m,第二个数组array2的长度

是n,,比较 array1[k//2-1] < array2[k//2-1],两个数组中小于等于 的元素共计不会超过 (k/2-1) + (k/2-1) <= k-2 个,那么对于两个数组array1[k//2-1]、array2[k//2-1]这个位置的最大元素是第k-1个。

数来说就不可能是合并后的中位数,反之,同理。

def getMidNum(array1,array2):
	def find(k):  
		index1 = 0 
		index2 = 0
		# 注意这个k一直记录是第几个数
		while True:
			if index1 == m:
				return array2[index2 + k - 1]
			if index2 == n:
				return array1[index1 + k - 1]
			if k == 1:
				return min(array1[index1],array2[index2])
				# 找到每个数组的需要比较的位置
			 newIndex1 = min(index1 + k//2 - 1, m-1)
			 newIndex2 = min(index2 + k//2 - 1, n-1)
			 if array1[newIndex1] <= array2[newIndex2]:
			   #去掉小的那个数的前面所有数,已经包括头尾所以要加个1 
			 	k -= newIndex1 - index1 + 1
			 	index1 = newIndex1 + 1
			 else:
			 	index2 = newIndex2 + 1
			 	k -= newIndex2 - index2 + 1
	m = len(array1)
	n = len(array2)
	L = m + n
	if L%2 != 0:
		return find((L+1)//2)
	else:
		return find(L//2 + L//2 + 1) / 2
	

六、数组跳跃问题

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标。

思路:数组可以到达下标y位置的前提是前面的位置存在一个位置i使得(i+nums[i])大于等

于y。只要前面n-1个位置存在一个x使得x+nums[x]大于等于下标n–1即可。

def jumpNum(nums):
	n = len(nums)
	max_step = 0
	# 这个地方可以是n,因为只要到达位置n-2不是零必定可以到达n-1位置;如果是零也不影响最后的结果。
	for i in range(n):
		if max_step >= i:
			max_step = max(max_step,i+nums[i])
		if max_step >= n - 1:
			return True
	else:
		return False
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值