牛客刷题day6(判断t1树中是否有与t2树拓扑结构,用两个栈实现队列,最长回文字符串,数组中出现的数字超过一半)

牛客刷题day6

1.判断t1树中是否有与t2树拓扑结构

题目

给定彼此独立的两棵二叉树,判断 t1 树是否有与 t2 树拓扑结构完全相同的子树。
设 t1 树的边集为 E1,t2 树的边集为 E2,若 E2 等于 E1 ,则表示 t1 树和t2 树的拓扑结构完全相同。

解题思路

使用递归
时间复杂度:O ( M ∗ N )
当root1什么都没有的时候,在root1里面找不到任何节点直接返回false。
当root2提前终止了,此时还没有遇到不符合root1树的节点,直接返回true。

核心代码
class Solution:
    def isContains(self , root1 , root2 ):
        # write code here
        if not root1 and not root2:
            return True
        if not root1 or not root2:
            return False
        return self.isEqual(root1,root2) or self.isContains(root1.left, root2) or self.isContains(root1.right, root2)
    
    def isEqual(self,root1,root2):
        if not root1 and not root2:
            return True
        if not root1 or not root2:
            return False
        return root1.val == root2.val and self.isEqual(root1.left, root2.left) and self.isEqual(root1.right, root2.right)
        

2.用两个栈实现队列

题目

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

解题思路

队列先进先出,栈是先进后出
将进栈的元素反转不就是队列?刚好两个栈,将进栈的元素出栈 不就刚好实现栈的反转 即实现队列

核心代码
class Solution:
    def __init__(self):
        self.stack1 ,self.stack2 = [],[]
        
    def push(self, node):
        # write code here
        self.stack1.append(node)
        
    def pop(self):
        # return xx
        if self.stack2:
            return self.stack2.pop()
        if not self.stack1:
            return None
        while self.stack1:
            self.stack2.append(self.stack1.pop())
        return self.stack2.pop()

3.最长回文字符串

题目

对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。
给定字符串A以及它的长度n,请返回最长回文子串的长度。
输入:“abc1234321ab”,12
输出:7

解题思路

1.(动态规划,O(n^2))
从第一个字符往后遍历,把每个字符都当作中心去向两边扩散,依次比较对称位置是否相等,当碰到左右边界停下。注意要分奇偶子串两种情况。
2. 马拉车算法,O(n))
在处理最长回文子串的时候,一般教科书上都会提一个线性的算法–Manacher大法,它可以将动态规划情况下的复杂度由n^2的复杂度降到线性。马拉车算法能将奇偶长度的子串归为一类,统一使用上面动态规划用的中心扩展法。它在原字符串中插入特殊字符,例如插入#后原字符串变成’#3#5#5#3#4#3#2#1#’。现在我们对新字符串使用中心扩展发即可,中心扩展法得到的半径就是子串的长度。但是在本题实际操练时,耗时上并没卵用。这里简单看下思路吧。说实话 这个算法我没看懂,不过为了给大家提供思路,还是贴出来
3.从头到尾遍历字符串,分奇偶字符串来判断,这个思想是牛客大佬的代码,我也是一步步打印才看明白,这个利用回文字符串特性,从头到尾扫描字符串,每增加一个新的字符,判断以这个字符结尾,大家可以用小例子试一下。且长度为maxLen+1或者maxLen+2的子串是否为回文,如果是,更新。这里长度为什么是maxLen+1或者maxLen+2,是要判断奇偶字符串。

核心代码

1.动态规划

class Solution:
    def getLongestPalindrome(self, A, n):
        def func(A, left, right):
            while left >= 0 and right < n and A[left] == A[right]:
                left -= 1
                right += 1
            return right - left - 1

        res = 0
        for i in range(n - 1):
            res = max(res, func(A, i, i), func(A, i, i + 1))
        return res
  1. 马拉车算法,O(n))
class Palindrome:
    def getLongestPalindrome(self, A, n):
        if n <= 1: return n
        # 每个字符之间插入 #
        ss = '$#' + '#'.join([x for x in A]) + '#`'
        p = [1] * len(ss)
        center = 0
        mx = 0
        max_str = ''
        for i in range(1, len(p)-1):
            if i < mx:
                j = 2 * center - i # i 关于 center 的对称点
                p[i] = min(p[j],mx-i)
            # 尝试继续向两边扩展,更新 p[i]
            while ss[i - p[i] ] == ss[i + p[i] ]: # 不必判断是否溢出,因为首位均有特殊字符,肯定会退出
                p[i] += 1
            # 更新中心
            if i + p[i] - 1 > mx:
                mx = i + p[i] - 1
                center = i
            # 更新最长串
            if 2 * p[i]-1 > len(max_str):
                max_str = ss[i - p[i]+1 : i + p[i]]
        maxLen = len(max_str.replace('#', ''))
        return maxLen

3.牛客大佬

class Solution:
    def getLongestPalindrome(self, A, n):
        # write code here
        max_len = 0
        for i in range(n):
        #	一定先判断奇数回文串,在判断偶数回文串
            oddNum = A[i-max_len-1:i+1]
            evenNum = A[i-max_len:i+1]
            if i-max_len-1>=0 and oddNum == oddNum[::-1]:
                max_len+=2
            elif i-max_len>=0 and evenNum == evenNum[::-1]:
                max_len+=1
        return max_len

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

题目

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

解题思路

1.先将数组排序,记录每个数字重复次数,满足题目条件就直接输出
2.建立字典,记录每个数字重复次数
3.直接使用python列表统计函数count() python list count()用法

核心代码

#1.解题思路1
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        numbers.sort()
        key = len(numbers)/2
        count =0
        value = 0
        for i in numbers:
            if value!=i:
                value = i
                count=1
            else:
                count+=1
            if count>key:
                return value
        return 0
# 解题思路2:
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        dict1 = dict()
        lenth = len(numbers)
        for item in numbers:
            if item not in dict1:
                dict1[item] = 1
            else:
                dict1[item] += 1
        for key, value in dict1.items():
            if value > lenth // 2:
                return key
        return 0
# 解题思路三

```python
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        for i in numbers:
            if numbers.count(i) > len(numbers)//2:
                return i
        return 0

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值