任务二打卡

题目一

题目

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例 1:

nums1 = [1, 3]
nums2 = [2]

则中位数是 2.0
示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

则中位数是 (2 + 3)/2 = 2.5

我的解答

1、我的想法比较简单,直接将两个数组相连,然后对数组排序,位于中间的一个(或两个的平均数)即为中位数,代入如下:

class Solution:
	def findMedianSortedArrays(self, nums1, nums2):
		nums3 = nums1 + nums2
		nums3.sort()
		l = len(nums3)
		if l % 2 == 1:
			return nums3[l // 2]
		else:
			return (nums3[l//2]+nums3[l//2-1])/2

运行结果
突然想起来排序是python里面数组自带的函数,对于其他语言可能没有这样的函数,这种投机的方法就行不通了。
2、后来想可以通过归并排序的思想来实习手动排序,因为题目中说了nums1和nums2是有序数组,只需执行最后一步合并就行,代码如下:

class Solution:
	def findMedianSortedArrays(self, nums1, nums2):
		nums3=[]
		i, j = 0, 0
		while (i < len(nums1) and j < len(nums2)):
			if nums1[i] <= nums2[j]:
				nums3.append(nums1[i])
				i += 1
			else:
				nums3.append(nums2[j])
				j += 1
		nums3 += list(nums1[i:])
		nums3 += list(nums2[j:])
		l = len(nums3)
		if l % 2 == 1:
			return nums3[l//2]
		else:
			return (nums3[l//2]+nums3[l//2-1])/2

题目二

题目

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:

输入: “cbbd”
输出: “bb”

我的解答

1、简单粗暴的想法:列出所有的子串,然后判断是不是回文,结果不出意外的超时了?(为什么我的第一想法总是那么简单粗暴),代码如下:

class Solution:
	def longestPalindrome(self, s):
		max_len = 0
		max_str = ''
		l = len(s)
		for i in range(l):
			for j in range(i+1, l+1):
				if self.palindrome(s[i:j]):	# 子序列
					if j-i > max_len:
						max_len = j-i
						max_str = s[i:j]
		return max_str
		
	def palindrome(self, s):	# 检查是否为回文序列
		l = len(s)
		for i in range(l//2):
			if s[i] != s[l-i-1]:
				return False
		return True

超时
2、判断回文:从某个位置开始,往两边移动指针,看字符是否相同,这样只需遍历一遍字符串,代码如下:

class Solution:
	def longestPalindrome(self, s):
		start = 0
		end = 0
		for i in range(len(s)):
			len1 = self.palindrome(s, i, i)
			len2 = self.palindrome(s, i, i+1)	# 判断两个相同字符
			length = max(len1, len2)
			if length > end - start:
				start = i - (length-1)//2
				end = i + length//2
		return s[start:end+1]
			
	def palindrome(self, s, j, k):
		max_len = 0
		while (j>=0 and k<len(s) and s[j] == s[k]):
			j -= 1
			k += 1
		if max_len < k-j-1:
			max_len = k-j-1
		return max_len

运行结果

题目三

题目

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:

L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);
示例 1:

输入: s = “LEETCODEISHIRING”, numRows = 3
输出: “LCIRETOESIIGEDHN”
示例 2:

输入: s = “LEETCODEISHIRING”, numRows = 4
输出: “LDREOEIIECIHNTSG”
解释:

L D R
E O E I I
E C I H N
T S G

我的解答

1、这道题其实不难,主要是找出其中的规律,表明上看是字符的排列,其实可以直接看成字符下标的排列,进而转换成数字的排列,这样找规律就简单一些。由题目中的两个例子可以看出:第一行的数都差了2*numRows-2,最后一行也是,其实中间行竖排的部分也是,而中间行的其余元素与行数有关。因此可以如下代码:

class Solution:
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        if numRows == 1:
            return s
        s1 = ''
        for j in range(numRows):
            for i in range(len(s)):
                if i%(2*numRows-2)==j or i%(2*numRows-2)==2*numRows-2-j:
                    s1 += s[i]
        return s1

悲剧的是还是超时了,看来以后真的需要好好注意程序运行的效率了。
运行结果
2、前面的代码效率太低,主要是因为前面每次都需要遍历一遍,从中找出余数为行数的数字,换个角度想,每一行从行号开始,选出间隔为step的数,对于该行的其他数,可以看出它们的规律为j+step-2*i。因此代码如下:

class Solution:
	def convert(self, s, numRows):
		if numRows == 1:
			return s
		elif numRows > len(s):
			return s
		s1 = ''
		step = 2*numRows - 2
		for i in range(numRows):
			for j in range(i, len(s), step):
				s1 += s[i]
				if i!=0 and i!=numRows-1 and j+step-2*i<len(s):	# 找出每一行处于斜位置的数
					s1 += s[j+step-2*i]

		return s1

运行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值