算法练习题python解法

目录

入门:

1. 反转字符串

2. 螺旋矩阵

3. 斐波那契数列

4. 判断回文

5. 寻找峰值

6. 旋转数组

7. 最大公约数

简单:

8. 反转链表

9. 两数之和

10. 合并有序链表

11. 用两个栈实现队列

12. 跳台阶

13. 子数组的最大累加和问题

14. 判断链表中是否有环

15. 括号序列

16. 两个链表的第一个公共结点

17. 求平方根

17.1 在旋转过的有序数组中寻找目标值

18. 设计getMin功能的栈

19. 买卖股票的最好时机

20. 二叉树的最大深度

21. 单链表的排序

22. 平衡二叉树

23. 数组中出现次数超过一半的数字

24. 进制转换

25. 判断一个链表是否为回文结构

26. 求路径

27. 反转数字

28. 缺失数字

29. 判断二叉树是否对称

30. 删除有序链表中重复的元素

31. 二叉树中是否存在节点和为指定值的路径

32. 最长公共前缀

33. 回文数字

34. 二叉搜索树的第k个结点

35. 字符串变形

36. 换钱的最少货币数

37. 股票(无限次交易)

38. 二叉树的镜像

39. 判断t1树中是否有与t2树拓扑结构完全相同的子树

40. 合并二叉树

41. 将升序数组转化为平衡二叉搜索树

42. 扑克牌顺子

43. 第一个只出现一次的字符

44. 旋转数组的最小数字

45. 数字在升序数组中出现的次数

46. 未排序数组中累加和为给定值的最长子数组长度

47. 三个数的最大乘积

48. 旋转字符串

49. 01背包

50. 数组中只出现一次的数(其它数出现k次)

51. 二分查找-I

 

中等:

52. 排序

53. 最长公共字符串

54. 链表内指定区间反转


 

入门:

1. 反转字符串

写出一个程序,接受一个字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000)

示例1

输入:"abcd"

输出:"dcba"

解题代码:

#
# 反转字符串
# @param str string字符串 
# @return string字符串
#
class Solution:
    def solve(self , str ):
        # write code here
        li = list(str)
        # list反转内置函数
        #l.reverse()
        #return "".join(l)
        i = 0
        j = len(li) - 1
        while i < j:
            tmp = li[i]
            li[i] = li[j]
            li[j] = tmp
            i += 1
            j -= 1
        return "".join(li)

2. 螺旋矩阵

给定一个m x n大小的矩阵(m行,n列),按螺旋的顺序返回矩阵中的所有元素。

输入:[[1,2,3],[4,5,6],[7,8,9]]

输出:[1,2,3,6,9,8,7,4,5]

#
# 
# @param matrix int整型二维数组 
# @return int整型一维数组
#
class Solution:
    def spiralOrder(self , matrix ):
        # write code here
        # matrix = [[1,2,3],[4,5,6],[7,8,9]]
        # matrix[0] = [1,2,3]
        # matrix矩阵如下:
        # 1 2 3
        # 4 5 6 
        # 7 8 9
        res = []
        while matrix:
            res += matrix[0]
            # zip(*matrix[1::]) = [(4,7), (5,8), (6,9)]
            matrix = zip(*matrix[1:])[::-1]
            # matrix = [(6,9), (5,8), (4,7)]
        return res

3. 斐波那契数列

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。

n\leq 39n≤39

输入:4

返回值:3

# -*- coding:utf-8 -*-
class Solution:
    def Fibonacci(self, n):
        # write code here
        s = [0] * (n+1)
        if n == 0:
            return  0
        if n == 1:
            return  1
        if n == 2:
            return  1
        s[0]=0
        s[1]=1
        if n > 1:
            for i in range(2, n+1):
                s[i] = s[i-1] + s[i-2]
        return s[n]

4. 判断回文

给定一个字符串,请编写一个函数判断该字符串是否回文。如果回文请返回true,否则返回false。

输入:"absba"

返回值:true

输入:"yamatomaya"

返回值:false

备注:字符串长度不大于1000000,且仅由小写字母组成

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
# 
# @param str string字符串 待判断的字符串
# @return bool布尔型
# 回文:从左至右和从右至左一样的字符串
#
class Solution:
    def judge(self , str ):
        # write code here
        list1 = list(str)
        list2 = list1[:]
        list1.reverse()
        return list1 == list2
        # 法二:字符串翻转,步长为-1
        # return str == str[::-1]

5. 寻找峰值

山峰元素是指其值大于或等于左右相邻值的元素。给定一个输入数组nums,任意两个相邻元素值不相等,数组可能包含多个山峰。找到索引最大的那个山峰元素并返回其索引。

假设 nums[-1] = nums[n] = -∞。

输入:[2,4,1,2,7,8,4]

返回值:5

#
# 寻找最后的山峰
# @param a int整型一维数组 
# @return int整型
#
class Solution:
    def solve(self , a ):
        # write code here
        if a[len(a)-1] > a[len(a)-2]:
            return len(a)-1
        for i in range(len(a)-2,1,-1):
            if a[i] >= a[i-1] and a[i] > a[i+1]:
                return i 
        if a[0] > a[1]:
            return 0

6. 旋转数组

一个数组A中存有N(N&gt0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0 A1 ……AN-1 )变换为(AN-M …… AN-1 A0 A1 ……AN-M-1 )(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

输入:6,2,[1,2,3,4,5,6]

返回值:[5,6,1,2,3,4]

备注:(1<=N<=100,M>=0)

#
# 旋转数组
# @param n int整型 数组长度
# @param m int整型 右移距离
# @param a int整型一维数组 给定数组
# @return int整型一维数组
#
class Solution:
    def solve(self , n , m , a ):
        # write code here
        m = m % n
        if m == 0 or n == 1:
            return a
        # 1.整体反转
        a[:] = a[::-1]
        # 2.反转前m个元素
        a[0:m] = a[m-1::-1]
        # 3.反转后n-m个元素
        a[m:n] = a[n-1:m-1:-1]
        return a

7. 最大公约数

求出两个数的最大公约数,如果有一个自然数a能被自然数b整除,则称a为b的倍数,b为a的约数。几个自然数公有的约数,叫做这几个自然数的公约数。公约数中最大的一个公约数,称为这几个自然数的最大公约数。

输入:3,6

返回值:3

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 求出a、b的最大公约数。
# @param a int 
# @param b int 
# @return int
#
# a和b的最大公约数等于 b%(a%b),如果余数为0,公约数为除数
class Solution:
    def gcd(self , a , b ):
        # write code here
        tmp = 0
        while b != 0:
            tmp = a % b
            a = b
            b = tmp
        return a
        

简单:

8. 反转链表

输入一个链表,反转链表后,输出新链表的表头。

输入:{1,2,3}

返回值:{3,2,1}

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        # write code here
        tmp = None
        pre = None
        while(pHead):
            # 先把当前节点的下一个节点保存
            tmp = pHead.next
            # 然后转向
            pHead.next = pre
            # 再把pre放到当前节点
            pre = pHead
            # 当前节点后移
            pHead = tmp
        return pre

9. 两数之和

给出一个整数数组,请在数组中找出两个加起来等于目标值的数,

你给出的函数twoSum 需要返回这两个数字的下标(index1,index2),需要满足 index1 小于index2.。注意:下标是从1开始的

假设给出的数组中只存在唯一解

例如:

给出的数组为 {20, 70, 110, 150},目标值为90
输出 index1=1, index2=2

输入:[3,2,4],6

返回值:[2,3]

说明:因为 2+4=6 ,而 2的下标为2 , 4的下标为3 ,又因为 下标2 < 下标3 ,所以输出[2,3]

#
# 
# @param numbers int整型一维数组 
# @param target int整型 
# @return int整型一维数组
#
class Solution:
    def twoSum(self , numbers , target ):
        # write code here
        for i in range(len(numbers)):
            if numbers[i] > target:
                continue
            for j in range(i+1, len(numbers)):
                if numbers[i] + numbers[j] == target:
                    return [i+1, j+1]

10. 合并有序链表

将两个有序的链表合并为一个新链表,要求新的链表是通过拼接两个链表的节点来生成的,且合并后新链表依然有序。

输入:{1},{2}

返回值:{1,2}

输入:{2},{1}

返回值:{1,2}

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

#
# 
# @param l1 ListNode类 
# @param l2 ListNode类 
# @return ListNode类
#
class Solution:
    def mergeTwoLists(self , l1 , l2 ):
        # write code here
        # head是把当前头结点记录,0不影响数据,只是占位
        if not l1 and not l2: return None
        tmp = ListNode(0)
        # tmp是为了记录新链表
        head = tmp
        while True:
            # 第一个链表为空,把第二个链表接上,break
            if not l1:
                tmp.next = l2
                break
            # 第二个链表为空,把第一个链表接上,break
            elif not l2:
                tmp.next = l1
                break
            # 第一个链表小于第二个链表的值,把第一个链表的val给新链表
            elif l1.val <= l2.val:
                tmp.next = l1
                l1 = l1.next
                tmp = tmp.next # 注意l1和tmp都要后移
            # 否则把第二个链表的val给新链表
            elif l1.val > l2.val:
                tmp.next = l2
                l2 = l2.next
                tmp = tmp.next # 注意l2和tmp都要后移
        return head.next # 第一个是0,返回头结点的后面next

11. 用两个栈实现队列

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

# -*- coding:utf-8 -*-
# 堆栈直接append(a),pop()出入,默认删除最后一个
# 队列append(a),pop(0)出入,队列从第一个开始删除
class Solution:
    def __init__(self):
        self.stack1 = []
        self.stack2 = []
        
        
    def push(self, node):
        # write code here
        # 栈1用来入队列,栈和队列的入是一样的,直接append
        self.stack1.append(node)
        
    def pop(self):
        # return xx
        # 栈2用来出队列,当栈2为空时,栈1全部出栈到栈2,栈2再出栈 
        if self.stack2 == []:
            while self.stack1:
                self.stack2.append(self.stack1.pop())
        return self.stack2.pop()

12. 跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

# -*- coding:utf-8 -*-
class Solution:
    def jumpFloor(self, number):
        # write code here
        if number<=1: return 1
        dp = [] * (number+1)
        dp[0] = dp[1] = 1
        for i in range(2,number+1):
            dp[number] = dp[number-1] + dp[number-2]
        return dp[number]

13. 子数组的最大累加和问题

给定一个数组arr,返回子数组的最大累加和

例如,arr = [1, -2, 3, 5, -2, 6, -1],所有子数组中,[3, 5, -2, 6]可以累加出最大的和12,所以返回12.

题目保证没有全为负数的数据

[要求]

时间复杂度为O(n)O(n),空间复杂度为O(1)O(1)

输入:[1, -2, 3, 5, -2, 6, -1]

返回值:12

#
# max sum of the subarray
# @param arr int整型一维数组 the array
# @return int整型
#
class Solution:
    def maxsumofSubarray(self , arr ):
        # write code here
        # dp[i]为下标i之前的大于0的最大累加和,当累加和小于0时,重新开始累加
        dp = [0] * (len(arr)+1)
        dp[0] = arr[0]
        for i in range(1,len(arr)):
            if dp[i-1] >= 0:
                dp[i] = dp[i-1] + arr[i]
            else:
                dp[i] = arr[i]
        return max(dp)

 

14. 判断链表中是否有环

判断给定的链表中是否有环。如果有环则返回true,否则返回false。

你能给出空间复杂度O(1)的解法么?

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

#
# 
# @param head ListNode类 
# @return bool布尔型
#
class Solution:
    def hasCycle(self , head ):
        # write code here
        # 快慢指针 解决链表中是否有环,快指针每次走两步,慢指针每次走一步
        # 如果相遇了就证明有环,如果没有相遇(快指针遇到了None)就证明没有环。
        # 其中需要注意的是判断空链表,以及快指针为空和即将为空的情况
        quick = head
        slow = head
        while quick and quick.next:
            quick = quick.next.next
            slow = slow.next
            if quick == slow:
                return True
        return False

15. 括号序列

给出一个仅包含字符'(',')','{','}','['和']',的字符串,判断给出的字符串是否是合法的括号序列
括号必须以正确的顺序关闭,"()"和"()[]{}"都是合法的括号序列,但"(]"和"([)]"不合法。

输入:"["

返回值:false

输入:"[]"

返回值:true

#
# 
# @param s string字符串 
# @return bool布尔型
#
class Solution:
    def isValid(self , s ):
        # write code here
        # 1.压栈和取栈
        # '(','[','{' 这三个就压栈
        # ')',']','}' 这三个就取栈,取栈时判断一下是不是对应的括号,如果是就取栈成功,不是就不能取。
        # 这样最后看栈是不是为空,不为空就说明顺序不正确
        # 2.'()','[]','{}'替换为'',最后字符串为空就true
        stack = []
        x = ['(', '{', '[']
        y = [')', '}', ']']
        for i in s:
            if i in x:
                stack.append(i)
            
            elif i in y:
                # 若i为}, 栈顶元素为{. 
                # ps: x[y.index(i)]为{
                if stack and stack[-1] == x[y.index(i)]:
                    stack.pop()
                elif stack == []:
                    stack.append(i)

        if stack == []:
            return True 
        else:
            return False

16. 两个链表的第一个公共结点

输入两个无环的单链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        # write code here
        if pHead1 == None or pHead2 == None:
            return None
        # 什么是公共节点,两个链表从某一节点开始,他们的next都指向同一个节点。
        # 但由于是单向链表的节点,每个节点只有一个next,因此公共节点之后他们的所有节点都是重合的。
        # 两个链表从头开始遍历,next相等时返回
        p1 = pHead1
        p2 = pHead2
        while p1 != p2:
            p1 = p1.next
            p2 = p2.next
            if p1 != p2:
                # 若到最后一个节点,又从头开始
                if p1 == None:
                    p1 = pHead1
                if p2 == None:
                    p2 = pHead2
        return p1

17. 求平方根

实现函数 int sqrt(int x).

计算并返回x的平方根(向下取整)

#
# 
# @param x int整型 
# @return int整型
#
class Solution:
    def sqrt(self , x ):
        # write code here
        if x==0:
            return 0
        left = 1
        
        right = x
        while left <= right:
            # /表示浮点数除法,//表示整数除法
            mid = (left + right) / 2
            tmp = mid * mid
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值