2023.10.10

高总 2023-10-10 241 10/10

还行,稳定的一天。

第一题

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

题目解(Python3):

代码之前:首先想到的是终止时刻,可以找到其中len最短的元素,循环到该长度值的时候终止,这个我看到很多官方解也写了,是一个比较好的方向,接下来的想法是先让前两组元素先比较出一组较短的公共前缀,然后存储这个前缀,接着跟剩下所有的剩余元素比较,遇到不同的就删掉这个位置上的公共前缀,接着再比较,最后通过输出K得到解。

代码中:遇到了很多问题,最后在chatgpt的帮助下完成了这个代码的书写,首先是一开始寻找长度最短的元素的时候,不知道min这个函数需要指定keys值来输出长度最小的元素,在我一开始测试的时候输入s=["swsw","ssadaobdqnwbhioq"],调用min函数的时候,输出总是后边那个,查了一下之后知道了min(s) 返回的是列表 s 中的最小元素,根据默认的字符串比较规则,也就是按照字母顺序进行比较。在字母顺序中,小写字母排在大写字母之前。a排在w之后也就比较好理解了。但是一开始想到的办法是挨个遍历,然后将遍历过程中的每个元素长度存储,最后找到其中的最小值,即为以下代码:

a =[None]*len(strs)
for i in range(len(strs):
    a[i]=len(strs[i])
return min(a)

首先是这种写法比较繁琐,中间用到了循环,可能会导致空间的开销比较大。

在研究过后采用了另一种写法

min_len=min(len(a) for a in strs)

少了很多墨迹的部分,少了额外创建的列表。但还不是最简的,最简的应该是

min_len=len(min(strs,key=len))

连循环都不用。

接下来放一下一开始我写的代码

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        b = [None] * len(strs)
        for i in range(0,len(strs)):
            b[i] = len(strs[i])
        k = [None] * max(b)
        for j in range(min(b)):
            if strs[0][j]==strs[1][j]:
                k[j]=strs[1][j]
            else:
                return ""
        k = list(filter(lambda item: item is not None, k))
        for c in range(2,len(strs)):
            for d in range(len(k)):
                if k[d]!=strs[c][d]:
                    return "".join(map(str, k[:d]))
            break

这里还出现的一个问题是,在创建过那个空列表后,最后输出的K总有None这个元素,没办法,使用list(filter(lambda item: item is not None, k))

去掉列表中的None,这时候一部分的测试用例已经能跑通了,在提交的时候发现有一些测试用例没法通过,还是缺少了对边界问题的考虑,例如当输入[""]或["",""]时会输出null,这时候改进一下,输出对边界值的思考。加入如下代码:

if all(s== "" for s in strs):
    return ""

即当给定字符串为空时输出空集。后来再测试用例时候发现还不对,因为有一种情况是["","b"],按照我的理解应该输出null,但是官方给的文档输出的是"",这个逻辑就改成了看到""即输出"",all改成any更好一点。

另一方面,只有一个元素的时候,需要输出自身,因此还需要以下代码:

if len(strs)==1:
    return strs[0]

改了半天之后,又发现了新的问题,第一次输出K的情况下会输出相间隔的相同字母,是个大问题,本来写到这不打算写了,但是后来又想到正好可以舍弃对比后None之前的字符,因为间隔是None,输出第一个None之前的字母正好是那个,因此又有以下代码:

result=[]
for p in k:
    if p is None:
        break
    result.append(p)

这样result就存储了正确的k

边界问题:

第二题:

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

  • 例如,121 是回文,而 123 不是。

题目解(Python3):

class Solution:
    def isPalindrome(self, x: int) -> bool:
        x=str(x)
        a = [None] * len(x)
        for i in range(len(x)):
            a[i]=x[i]
        b=list(a)
        a.reverse()
        if b == a:
            return True
        else:
            return False
class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if  any(s==""for s in strs):
            return ""
        if len(strs) == 1:
            return strs[0]
        b = [None] * len(strs)
        for i in range(0,len(strs)):
            b[i] = len(strs[i])
        k = [None] * min(b)
        for j in range(min(b)):
            if strs[0][j]==strs[1][j]:
                k[j]=strs[1][j]
        result=[] 
        for p in k: 
            if p is None:
                break
            result.append(p)
        k = result
        if len(strs)==2:
            return "".join(map(str, k))
        if len(strs)>2:
            for c in range(2,len(strs)):
                for d in range(len(k)):
                    if k[d]!=strs[c][d]:
                        return "".join(map(str, k[:d]))
            return "".join(map(str, k))

代码之前:这个就比较简单了,但是我看到leetcode上的出现率还是比较高,可能比较水的面试比较爱考,因为一开始的X是int类型的不支持逆序操作,因此将X转化为字符串格式,接着创建一个空列表,编遍历字符串边用字符串的数字填充列表,接着翻转列表,最后判断,整体比较简单,没什么好说的。

代码中:主要的一点点小问题只出现在python这个解释器中,当你将一个列表赋值给另一个变量时,实际上是将相同的列表对象的引用分配给了这两个变量。这意味着如果你更改其中一个变量所引用的列表,另一个变量也会反映出相同的更改,因为它们实际上引用的是同一个列表对象。因此在翻转前赋值的时候,不能直接b=a,应该使用b=list(a)或b=a[:]来创建一个全新的列表,不然结果就是在b改变的同时a也发生改变。

边界问题:也没有产生什么边界的问题,一些诸如负数,0这些问题都不是什么大问题,因为使用的是列表,不管你什么结构。

示例代码:

class Solution(object):
    def isPalindrome(self, x):
        x=str(x)
        if x[::-1]==x:
            return True
        else:
            return False

...有点温酒斩华雄的感觉,但确实是因为我忘了切片操作也能实现翻转的效果。

- THE END -

高总

10月11日21:08

最后修改:2023年10月11日
1

非特殊说明,本博所有文章均为博主原创。