牛客网——python之剑指0ffer之67道在线编程——jz26-jz30

jz26 二叉搜索树与双向链表

题目描述

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

题目链接

思路分析:

二叉搜索树特点:
根节点的值大于其左子树中任意一个节点的值,小于其右节点中任意一节点的值,这一规则适用于二叉搜索树中的每一个节点。

根据二叉搜索树的特点,中序遍历二叉树可得到排序的结点。因此,可以中序遍历加上递归处理解决这问题。

【代码实现】

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Convert(self, pRootOfTree):
        # write code here
        #1、如果树为空,或没有左右子树,则返回原树
        if not pRootOfTree:
            return pRootOfTree
        if not pRootOfTree.left and not pRootOfTree.right:
            return pRootOfTree
        #中序遍历加递归
        #2、处理左子树:先调用自身判断即前面那一部分,如果都存在,则继续下一行
        self.Convert(pRootOfTree.left)
        left=pRootOfTree.left
        #2.1连接根与左子树最大节点
        if left:
            while (left.right):
                left=left.right
            pRootOfTree.left,left.right=left,pRootOfTree
        #3.1处理右子树
        self.Convert(pRootOfTree.right)
        right=pRootOfTree.right
        #3.2连接根与右子树最小结点
        if right:
            while(right.left):
                right=right.left
            pRootOfTree.right,right.left=right,pRootOfTree
        #4、while循环更新BST
        while(pRootOfTree.left):
            pRootOfTree=pRootOfTree.left
        return pRootOfTree


jz27 字符串的排列

题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

题目链接

思路分析:

1、固定第一元素,第一元素的可能取值为字符串的不同字符
2、固定第一元素的情况下,其他元素随便排列
3、利用集合添加并去重的特点,创建一个集合,添加所有可能的排列

集合添加去重:

a=[1,2,3,2]
b=set(a)
b

{1, 2, 3}

b.add(3)
b

{1, 2, 3}

b.add(4)
b

{1, 2, 3, 4}

sorted(b)#集合b形式变为列表形式

[1, 2, 3, 4]
【代码实现】

# -*- coding:utf-8 -*-
class Solution:
    def Permutation(self, string):
        #1、判断字符串长度
        if len(string)<=1:
            return string
        # 2、创建集合,以存放可能的字符串
        res=set()
        # 3、遍历字符串,固定第一个元素,第一个元素可取字符串中所有字母;然后递归
        for i in range(len(string)):
            for j in self.Permutation(string[:i]+string[i+1:]):#第一元素固定,其他元素随便排列
                res.add(string[i]+j)#集合添加方法add(),添加的过程中会去重,如果添加元素,原集合中有,就不再添加了
        return sorted(res)#集合排序以后,会变成列表的形式

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

题目描述

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

题目链接

思路分析:

排序比较法

1、数组排序
2、计算出中位数
3、如果中位数的出现次数大于数组长度的一半,则返回中位数,否则不存在,返回0。
【代码实现】

# -*- coding:utf-8 -*-
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        numbers=sorted(numbers)
        mid_len=len(numbers)//2
        median=numbers[mid_len]#中位数
        if numbers.count(median)>mid_len:
            return median
        else:
            return 0

jz29 最小的k个数

题目描述

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

题目链接

思路分析:

这道题比较简单,只需将数组排序,然后再取前k个数即可
但是必须注意特殊情况的处理:
1、如果数组为空,则返回列表即可。
2、如果取出的个数大于数组的长度,返回空值。

【代码实现】

# -*- coding:utf-8 -*-
class Solution:
    def GetLeastNumbers_Solution(self, lists, k):
        # write code here
        if lists is None:
            return lists
        n=len(lists)
        if k>n:
            return []
        lists=sorted(lists)
        return lists[:k]

jz30 连续子数组的最大和

题目描述

HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)

题目链接

思路分析:

动态规划法
初始化连续和max_sum为零,建一空列表list_sum存储连续和。
1、遍历数组的开头往下走,max_sum记录连续的和,并将连续和添加到list_sum表里。

  • 若max_sum大于零,继续累加
  • 若max_sum小于零,则令max_sum归零,从下一元素开始累计加和。

3、返回list_sum表里的最大值,即为所求。
【代码实现】

# -*- coding:utf-8 -*-
class Solution:
    def FindGreatestSumOfSubArray(self, array):
        # write code here
        if len(array)<=0:
            return []
        max_sum=0
        list_sum=[]
        for a in array:
            max_sum=max_sum+a
            list_sum.append(max_sum)
            if max_sum>0:
                continue
            else:
                max_sum=0
        print(list_sum)
        return max(list_sum)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值