笨方法刷 leetcode(一)

最近在看leetcode,并且正在上面刷一些简单级别的题目(不过说真的,这些题真的简单吗??或许是我太菜,有些感觉也很难……)

本篇记录5道题的解题思路,可能都是最笨的方法

No.1 判断字符是否唯一

题目描述

实现一个算法,确定一个字符串 s 的所有字符是否全都不同

示例 1:

输入: s = "leetcode"

输出: false

示例 2:

输入: s = "abc"

输出: true

限制:

0 <= len(s) <= 100

原题链接:

https://leetcode-cn.com/problems/is-unique-lcci/

解决思路:

python中有一个内置函数set(),它的一个特性就是->可以利用已有列表、字符串、元组或字典的内容来创建集合,其中重复的值会被丢弃;

所以就可以通过set()来得到一个剔除重复值后的集合,并且比较两者的长度,如果长度相等,则证明字符唯一;如果长度不等,则字符不唯一

代码如下:

class Solution(object):

    def isUnique(self, astr):
        """
        :type astr: str
        :rtype: bool
        """
        len_1 = len(astr)  # 获取传入字符串的长度
        b = set(astr)  # 使用set()函数将传入字符串转为一个集合,该集合剔除了重复的元素
        len_2 = len(b)  # 获取集合的长度
        if len_1 == len_2:  # 对比原字符串和集合的长度,如果两者相等,表明字符串无重复;否则表示有重复元素
            print("true")
            return True
        else:
            print("false")
            return False

No.2 两数之和

题目描述

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。  

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。     


示例:  给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]

原题链接:

https://leetcode-cn.com/problems/two-sum/

解决思路:

用第1个数字依次与其后面的数字相加,判断结果是否为目标值;然后用第2个数字依次与其后面数字相加,判断结果是否为目标值;         依此类推,用第n个数,与其后的数字相加,这样就做到了任意2个数字(不重复)的叠加求和

代码如下:

class Solution(object):
    def twoSum(self, nums, target):
        """
        思路:用第1个数字依次与其后面的数字相加,判断结果是否为目标值;然后用第2个数字依次与其后面数字相加,判断结果是否为目标值
        依次类推,用第n个数,与其后的数字相加,这样就做到了任意2个数字的不重复叠加求和
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        for i in range(0, len(nums)):  # 定义第一个for循环,从第一个数字开始,深度为字符串列表的长度
            for j in range(i + 1, len(nums)):  # 内嵌一个for循环,从第二个数字开始,深度为字符串列表长度,
                if nums[i] + nums[j] == target:  # 先用第一个数字(nums[i]代表加号左侧数字)分别与其后的数字(nums[j]加号右侧数字)叠加,判断结果是否为目标值
                    return i, j  # 如果相加得到目标值,则返回下角标组合的列表
                else:
                    continue  # 如果不是,则继续循环

No.3 回文数

题目描述

判断一个整数是否是回文数。

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

示例 1:

输入: 121

输出: true

示例 2:

输入: -121

输出: false

解释: 从左向右读, 为 -121 。从右向左读, 为 121- 。因此它不是一个回文数。

示例 3:

输入: 10

输出: false

解释: 从右向左读, 为 01 。因此它不是一个回文数。

原题链接:

https://leetcode-cn.com/problems/palindrome-number/

解决思路:

把输入的数字先转换成列表,反向取出来,也就是从最后一个开始提取,然后依次追加到一个新的列表并组合成一个新的字符串,最后与原字符串判断是否相等

代码如下:

class Solution(object):
    def isPalindrome(self, x):
        """
        解决思路:把输入字符串转换成列表,反向取出来,也就是从最后一个开始提取,然后依次追加到一个新的列表并组合成一个新的字符串,然后与原字符串判断是否相等
        :type x: int
        :rtype: bool
        """

        string = str(x)  # 将输入的整数转为字符串
        s_list = list(string)  # 将字符串转为列表
        n_list = []  # 定义一个空列表,用于存储下面反向输出的列表
        for t in range(0, len(s_list)):
            n_list.append(s_list[len(s_list)-t-1])

        n_string = "".join(n_list)  # 将新的列表转为字符串

        if string == n_string:  # 判断2个字符串的值是否相等(注意⚠️:不要用is判断,is是用来判断其id值是否相等,==判断其值是否相等)
            return True
        else:
            return False

另一种写法更简单些,把输入数字转换成字符串后,直接通过切片的方法,反向输出得到一个新的字符串

def isPalindrome_2(self, x):
    string = str(x)
    new_string = string[::-1]

    if string == new_string:
        return True
    else:
        return False

No.4 整数反转

题目描述

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

示例 1:输入: 123输出: 321
示例 2:输入: -123输出: -321
示例 3:输入: 120输出: 21
注意:假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231,  231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0

原题链接:

https://leetcode-cn.com/problems/reverse-integer/

解决思路:

先把整数转换为字符串,然后利用字符串切片的方法将其进行反转(注意:如果传入的是负数,需要保留"-"前缀,只将后面的字符反转)

代码如下:

class Solution(object):

    def reverse(self, x):
        """

        :type x: int
        :rtype: int
        """
        l = str(x) # 把输入的数字转换为字符串
        if l[0] == "-":  # 如果首位字符是"-"(也就是说输入一个负数)
            s = l[1:]  # 截取"-"之后的部分
            new = s[::-1]  # 将"-"之后的部分进行反转,得到一个新字符串
            i = ""  # 定义一个空字符串
            for t in new:
                i += t  # 遍历新列表中的值,并将结果一个个追加到空字符串中
            i = "-" + i  # 将"-"与最终的字符串i组合,得到最终的字符串
        else:
            new = l[::-1]  # 如果首位字符不是"-",则直接进行反转

            i = ""
            for t in new:
                i += t

        if -2 ** 31 <= int(i) <= 2 ** 31 - 1:
            return int(i)  # 将反转后的字符串i转换为整型数字,并判断结果是否在允许范围内,如果在,则将其返回;如果不在,则返回0
        else:
            return 0

No.5 最长公共前缀

题目描述

编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例 1:输入: ["flower","flow","flight"]输出: "fl"
示例 2:输入: ["dog","racecar","car"]输出: ""解释: 输入不存在公共前缀。
说明:所有输入只包含小写字母 a-z 。

原题链接:

https://leetcode-cn.com/problems/longest-common-prefix/

解决思路:

这个把我难住了,后来看了官方题解,里面有一个横向扫描法和一个纵向扫描法,下面根据自己的理解来实现了一下

代码如下:

横向扫描法

class Solution(object):
    def longestCommonPrefix(self, strs):
        """
        横向扫描法
        :type strs: List[str]
        :rtype: str
        """
        if not strs:
            return ""
        else:
            prefix = strs[0]  # 把字符串列表中的第一个字符串赋给一个变量
            length = len(strs)  # 获取整个字符串列表的长度

            for t in range(1, length):
                prefix = self.common_start(prefix, strs[t])
                # 调用common_start方法比较2个字符串,提取公共前缀,然后将获取到的公共前缀再与后一个字符串比较
                if not prefix:  # 当在后续比较中没有公共前缀(即公共前缀为空时,退出循环)
                    break
            return prefix  # 循环完成后,返回最终的公共前缀

    @staticmethod
    def common_start(str1, str2):
        """
        获取2个字符的公共前缀
        :param str1:
        :param str2:
        :return:
        """
        length = min(len(str1), len(str2))  # 获取2个字符串的最小长度

        if length == 0:  # 如果最小字符串长度为0,则意味着有空字符串,所以公共前缀为""
            return ""

        else:
            common = ""  # 定义一个空字符串,用来存储公共前缀
            for i in range(0, length):  # 以最小长度字符串的长度作为遍历深度

                common += str1[i]  # 把字符串1的第i个字符追加到common中

                if str2.startswith(common):  # 利用自带的startswith()函数,判断字符串2是否以common为前缀,如果以common为前缀,则继续循环
                    continue

                else:  # 如果字符串2不是以common为前缀,则返回common除掉最后一个字符外的部分
                    return common[:-1]
            return common  # 如果一直满足if条件,则说明字符串2是以common为前缀,所以当循环走完后,返回最后的common字符串

纵向扫描法

class Solution(object):
    @staticmethod
    def longestCommonPrefix2(strs):
        """
        纵向扫描法
        :param strs:
        :return:
        """
        if not strs:  # 如果传入空列表,则返回空字符串
            return ""

        for i in range(0, len(strs[0])):  # 获取第一个字符串的长度,并以此作为循环深度

            c = strs[0][i]  # 获取第一个字符串,并且从其第一个字符开始遍历(以第一个字符串为纵向扫描依据,判断第一个字符串的各列是否与后续字符串的各列相同)

            for j in range(1, len(strs)):  # 获取整个字符串列表的长度,从第二个字符串开始分别与第一个字符串比对

                if i <= len(strs[j])-1:  # 在把第二个字符串的字符与第一个字符串的字符比对前,先判断后续字符串的长度是否大于等于第一个字符串的长度(防止提取后续字符串的字符时,出现溢出)

                    if strs[j][i] == c:  # 从第二个字符串开始,依次判断后续字符串的第i个字符是否与第1个字符串的第i个字符相等,如果相等,则通过,继续下一轮判断;

                        pass
                    else:  # 如果不相等,则退出循环,返回第一个字符串的前i个字符
                        print("第1个return")
                        return strs[0][:i]
                else:  # 如果后续字符串的长度比第一个字符串短,则strs[j][i]最终会溢出,此时退出循环,返回第一个字符串的前i个字符
                    print("第2个return")
                    return strs[0][:i]
        print("第3个return")
        return strs[0]  # 如果一直满足所有if条件,则说明第一个字符串的字符都是公共前缀,最终返回第一个字符串

未完……

原文地址:https://www.cnblogs.com/hanmk/p/13763481.html