刷题吧!

1.给出一个32位的有符号整数,实现整数中每位上的数字进行反转   ---> python3

 

  • 将整数转为字符串,进行反转,后再恢复为整数

class Solution(object):

    # 本题的思路就是先判断给定整数x的正负情况,把符号首先给提取出来

    def reverse(self, x):

        """

            :type x: int

            :rtype: int

        """

        # 定义用来标记给定整数x的正负情况,若x>=0, 则flag=1;反之,则flag=-1

        flag = 1 if x >= 0 else -1

       abs_x = abs(x)

       x_str = str(abs_x)                        # 将abs(x)变成字符串

       reverse_x_str = x_str[::-1]        # 将字符串x_str反转

      

       reverse_x_int = int(reverse_x_str) * flag          # 最后恢复成整数

       if -2 ** 31 <= reverse_x_int <= 2**31 - 1:

            return reverse_x_int

       else:

            return 0

 

if __name__ == "__main__":

      x = 231

      reverse_x = Solution().reverse(x)

      print(reverse_x)

 

 

  • 正常整数方法实现,利用余数*10累加的方法完成。需要注意的是,python对整数除法采用“向下取整”机制,所以正数和负数要区别运算。

def reverse(self, x):

        """

        :type x: int

        :rtype: int

        """

        num = 0

        if x == 0:

            return 0

        if x < 0:

            x = -x

            while x != 0:

                num = num*10 + x%10

                x = x//10                     # 此处注意要用‘//’取整

            num = -num

        else:

            while x != 0:

                num = num*10 + x%10

                x = x/10           

        if num>pow(2,31)-1 or num < pow(-2,31):      # 判是否出界

            return 0

        return num

 

2.判断一个数是否是回文数。回文数是指正序(从左到右)和倒序(从右到左)读都是一样的数

def is_huiwen(x):

    if x >= 0:

        x_str = str(x)

        x_reverse = x_str[::-1]

        x_int = int(x_reverse)

        if x == x_int:

            return True

        else:

            return False

    else:

        return None

        # print('负数没有回文数!')

       

x = 1524

print(is_huiwen(x))

 

 

3.给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。

字符          数值

I             1

V             5

X             10

L             50

C             100

D             500

M             1000        例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。

X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 

C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

示例 3:                                   示例 4:                                        示例 5:

输入: "IX"                              输入: "LVIII"                               输入: "MCMXCIV"

输出: 9                                   输出: 58                                      输出: 1994           解释: M = 1000, CM = 900, XC = 90, IV = 4.

 

 

 

 

4.编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。

 

示例 1:                                                                                  示例 2:

输入: ["flower","flow","flight"]                                        输入: ["dog","racecar","car"]

输出: "fl"                                                                              输出: ""                                                         解释: 输入不存在公共前缀。

只需要比较逐个字母ASCII码值,谁先出现小于的话,则为最小值 ,比较到最后则为最大值的存在,可以使用print()或者ipython测试

class Solution(object):

    def longestCommonPrefix(self, strs):

        """

              :type strs: List[str]

              :rtype: str

        """

        if not strs:                      # 判断是否为空

            return ''                    # 在使用max和min的时候已经把字符串比较了一遍

           

        s1 = min(strs)               # 当前列表的字符串中,每个字符串从第一个字母往后比较直至出现ASCII码 最小的字符串

        s2 = max(strs)              # 当前列表的字符串中,每个字符串从第一个字母往后比较直至出现ASCII码 最大的字符串   

        for i, c in enumerate(s1):         # 使用枚举变量s1字符串的每个字母和下标

            if c != s2[i]:                                # 比较是否相同的字符串,不相同则使用下标截取字符串

                return s1[:i]

        return s1

 

if __name__ == '__main__':

    s = Solution()

    print(s.longestCommonPrefix(["flower", "flow", "flight"]))

    print('123', s.longestCommonPrefix(["dog", "racecar", "car"]))

 

 

5.将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例:                         输入:1->2->4, 1->3->4

                                      输出:1->1->2->3->4->4

 

 

 

 

 

6.给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。不使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

示例 :            给定 nums = [0,0,1,1,1,2,2,3,3,4],函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。

说明:  为什么返回数值是整数,但输出的答案是数组呢?请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝

int len = removeDuplicates(nums);

 

// 在函数里修改输入数组对于调用者是可见的。

// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。

for (int i = 0; i < len; i++) {

    print(nums[i]);

}

 

方法1:

class Solution:

    def removeDuplicates(self, nums: List[int]) -> int:

        for i in range(len(nums)-1, 0, -1):

            if nums[i] == nums[i-1]: nums.pop(i)

        return len(nums)                    时间效率O(N^2)空间效率O(1),逆遍历可以防止删除某个元素后影响下一步索引的定位。每次删除数组元素会引发大量的数据迁移操作,使用以下算法解题效率更高

 

 

7.搜索插入位置.给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。你可以假设数组中无重复元素。

示例 1:       输入: [1,3,5,6], 5                             输出: 2

示例 2:       输入: [1,3,5,6], 2                             输出: 1

class Solution:

    def searchInsert(self, nums: List[int], target: int) -> int:

        n = len(nums)

        if target in nums:

            for i, num in enumerate(nums):

                if num == target:

                    return i

        else:

            for i in range(n):

                if target <= nums[0]:

                    return 0

                elif target > nums[n-1]:

                    return n

                else:

                    if target > nums[i] and target < nums[i+1]:

                        return i+1

 

 

8.报数.报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:

1.     1

2.     11

3.     21

4.     1211

5.     111221

1 被读作  "one 1"  ("一个一") , 即 11。

11 被读作 "two 1s" ("两个一"), 即 21。

21 被读作 "one 2",  "one 1" ("一个二" ,  "一个一") , 即 1211。给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。注意:整数顺序将表示为一个字符串。

示例 1:                     输入: 1                                         输出: "1"

示例 2:                     输入: 4                                         输出: "1211"

循环含义

每次外循环含义为给定上一个人报的数,求下一个人报的数;每次内循环为遍历上一个人报的数

具体思路

先设置上一人为'1',开始外循环,每次外循环先置下一人为空字符串,置待处理的字符num为上一人的第一位,置记录出现的次数为1;开始内循环,遍历上一人的数,如果数是和num一致,则count增加。若不一致,则将count和num一同添加到next_person报的数中,同时更新num和count。别忘了更新next_person的最后两个数为上一个人最后一个字符以及其出现次数!

class Solution:

    def countAndSay(self, n: int) -> str:

        prev_person = '1'

        for i in range(1,n):

            next_person, num, count = '', prev_person[0], 1

            for j in range(1,len(prev_person)):

                if prev_person[j] == num:count += 1

                else:

                    next_person += str(count) + num

                    num = prev_person[j]

                    count = 1

            next_person += str(count) + num

            prev_person = next_person

        return prev_person

 

 

9.最大子序和.给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:               输入: [-2,1,-3,4,-1,2,1,-5,4],                输出: 6

解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]

#max(nums)

#sum(nums[0:3])

 

temp = []

n = len(nums)

 

for i in range(1, n+1):    # 几个值相加

    for j in range(0, n-i+1):

        arrays = nums[j:j+i]

        for array in arrays:

            a = sum(array)

        temp.append(a)

        b = max(temp)

print(temp)

print(b)

 

1. 暴力求解

基本思路就是遍历一遍,用两个变量,一个记录最大的和,一个记录当前的和。时空复杂度貌似还不错......(时间复杂度 O(n)O(n),空间复杂度 O(l)O(l))

class Solution:

    def maxSubArray(self, nums: List[int]) -> int:

        tmp = nums[0]

        max_ = tmp

        n = len(nums)

        for i in range(1,n):

            # 当当前序列加上此时的元素的值大于tmp的值,说明最大序列和可能出现在后续序列中,记录此时的最大值

            if tmp + nums[i]>nums[i]:

                max_ = max(max_, tmp+nums[i])

                tmp = tmp + nums[i]

            else:

            #当tmp(当前和)小于下一个元素时,当前最长序列到此为止。以该元素为起点继续找最大子序列,

            # 并记录此时的最大值

                max_ = max(max_, tmp, tmp+nums[i], nums[i])

                tmp = nums[i]

        return max_

       

2. 分治法

分治法其他题解里讲的很清楚了。其实就是它的最大子序和要么在左半边,要么在右半边,要么是穿过中间,对于左右边的序列,情况也是一样,因此可以用递归处理。中间部分的则可以直接计算出来,时间复杂度应该是 O(nlogn)。代码如下:

class Solution:

    def maxSubArray(self, nums: List[int]) -> int:

        n = len(nums)

        if n == 1:            #递归终止条件

            return nums[0]

        else:

            max_left = self.maxSubArray(nums[0:len(nums) // 2])                       #递归计算左半边最大子序和

            max_right = self.maxSubArray(nums[len(nums) // 2:len(nums)])     #递归计算右半边最大子序和

       

        #计算中间的最大子序和,从右到左计算左边的最大子序和,从左到右计算右边的最大子序和,再相加

        max_l = nums[len(nums) // 2 - 1]

        tmp = 0

        for i in range(len(nums) // 2 - 1, -1, -1):

            tmp += nums[i]

            max_l = max(tmp, max_l)

        max_r = nums[len(nums) // 2]

        tmp = 0

        for i in range(len(nums) // 2, len(nums)):

            tmp += nums[i]

            max_r = max(tmp, max_r)

        #返回三个中的最大值

        return max(max_right,max_left,max_l+max_r)

 

 

10.最后一个单词的长度。给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度。

如果不存在最后一个单词,请返回 0 。

说明:一个单词是指由字母组成,但不包含任何空格的字符串。

示例:

输入: "Hello World"

输出: 5

s = "Hello World"

 

s = s.strip()

 

if len(s) != 0:

    return len(s.split(' ')[-1])

else:

    return 0

 

 

11.加一。给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。你可以假设除了整数 0 之外,这个整数不会以零开头。

示例 1:            输入: [1,2,3]                                                        示例 2:            输入: [4,3,2,1]

                         输出: [1,2,4]                                                                                 输出: [4,3,2,2]

                         解释: 输入数组表示数字 123。                                             解释: 输入数组表示数字 4321。    

 

遍历digits,判断每位是否为9,若不是则+1并返回,否则将此位置0对于digits里全为9的情况,需要扩展list,并将首位置为1

python

class Solution:

    def plusOne(self, digits: [int]) -> [int]:

        for i in range(len(digits)-1, -1, -1):

            if digits[i] != 9:

                digits[i] += 1

                return digits

            digits[i] = 0

        digits[0] = 1

        digits.append(0)

        return digits

 

class Solution:

    def plusOne(self, digits: List[int]) -> List[int]:

        i = len(digits) - 1

        while digits[i] == 9 and i >= 0:

            i = i - 1

        for j in range(i + 1, len(digits)):

            digits[j] = 0

        if i == -1:

            digits.insert(0,1)

        else:

            digits[i] += 1

        return digits

 

列表求和,加1,结果转化成列表

class Solution(object):

    def plusOne(self, digits):

        sums = 0

        for i in range(len(digits)):

            sums += 10**(len(digits)-1-i)*digits[i]

        sums_str = str(sums + 1)

        return [int(j) for j in sums_str]

 

 

12.爬楼梯。假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?注意:给定 n 是一个正整数。

示例 1:                                                                                       示例 2:

输入: 2                                                                                       输入: 3

输出: 2                                                                                       输出: 3

解释: 有两种方法可以爬到楼顶。                                    解释: 有三种方法可以爬到楼顶

1.  1 阶 + 1 阶                                                                              1.  1 阶 + 1 阶 + 1 阶

2.  2 阶                                                                                           2.  1 阶 + 2 阶

                                                                                                         3.  2 阶 + 1 阶

设爬 n个台阶有 f(n) 种可能:假设先爬1阶,剩下n-1 阶有f(n-1) 种可能;假设先爬2阶,剩下 n-2阶有 f(n-2) 种可能,因此爬n阶可以转化为两种爬n-1阶问题之和:f(n) = f(n-1) + f(n-2);

不难看出,这就是斐波那契数列公式,此题可转化为求斐波那契数列第n项。

PythonJava

class Solution:

    def climbStairs(self, n: int) -> int:

        a, b = 1, 1

        for _ in range(n-1):

            a, b = a + b, a

        return a

 

 

 

13.删除排序链表中的重复元素。给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

示例 1:                                                                                         示例 2:

输入: 1->1->2                                                                              输入: 1->1->2->3->3

输出: 1->2                                                                                    输出: 1->2->3

 

n = len(l)

ll = []

 

for i in range(n):

    if l[i] not in ll:

        ll.append(l[i])

print(ll)

 

class Solution:

    def deleteDuplicates(self, head: ListNode) -> ListNode:

        if head == None or head.next== None:

            return head       

        p = head

        target = p.val

        while True:

               

            if p.next.val == target:

                p.next = p.next.next               

            else:

                target = p.next.val

                p = p.next

               

            if p.next is None:

                break

               

        return head

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值