牛客刷题day10(进制转换,链表指定区间反转,最长公共子序列,数组中未出现的最小正整数,表达式求值,判断一个链表是否为回文结构)

牛客刷题day10

1.进制转换

题目

给定一个十进制数M,以及需要转换的进制数N。将十进制数M转化为N进制数
输入7,2 返回值"111"

解题思路

除N取余,然后倒序排列,高位补零。
说M是32位整数,所以有可能是负数和0,如果是0的话直接返回,如果是负数,就先转化成正数,最后再加上符号位。

核心代码
class Solution:
    def solve(self , M , N ):
        if M==0:
            return 0
        # write code here
        if M<0:
            M=-M
            sign ='-'
        else:
            sign=''
        Str=''
        while M:
            rest = M%N
            if rest>=10:
                rest = chr((rest-10)+ord('A'))
            Str+=str(rest)
            M=M//N
        Str=sign+Str[::-1] 
        return Str

2.链表指定区间 反转

题目

将一个链表\ m m 位置到\ n n 位置之间的区间反转,要求时间复杂度 O(n)O(n),空间复杂度 O(1)O(1)。
例如:
给出的链表为 1→2→3→4→5→NULL, m=2,n=4m=2,n=4,
返回 1→4→3→2→5→NULL.
注意:
给出的 mm,nn 满足以下条件:
链表长度1≤m≤n≤链表长度
输入:{1,2,3,4,5},2,4
返回值:{1,4,3,2,5}

解题思路

先找到n的位置,使用双指针,在m-n区间使用头插法将链表反转
在这里插入图片描述

核心代码
class Solution:
    def reverseBetween(self , head , m , n ):
        # write code here
        if not head:
            return head
        newHead = ListNode(0)
        newHead.next =head
        cur,pre = head,newHead
        for i in range(m-1):
            pre =cur
            cur = cur.next
        for j in range(n-m):
            temp = cur.next
            cur.next =temp.next
            temp.next = pre.next
            pre.next = temp
        return newHead.next

3.最长公共子序列

题目

给定两个字符串str1和str2,输出两个字符串的最长公共子序列。如果最长公共子序列为空,则输出-1。
示例1
输入
“1A2C3D4B56”,“B1D23CA45B6A”
返回值
“123456”
说明
"123456"和“12C4B6”都是最长公共子序列,任意输出一个

解题思路

动态规划
在这里插入图片描述

核心代码
class Solution:
    def LCS(self, s1, s2):

        # write code here
        m, n = len(s1), len(s2)
        # if m > n:
        #     m, n = n, m
        #     s1, s2 = s2, s1
        dp =[[''] *(n +1)  for _ in range(m+1)]
        for i in range(1, m + 1):
            for j in range(1, n + 1):
                if (s2[j - 1] == s1[i - 1]):
                    dp[i][j] = dp[i - 1][j - 1] + s2[j - 1]
                else:

                    if len(dp[i - 1][j]) > len(dp[i][j - 1]):
                        dp[i][j] = dp[i - 1][j]
                    else:
                        dp[i][j] = dp[i][j - 1]

        if dp[-1][-1]:

            return dp[-1][-1]
        else:
            return -1

今天运行代码发现一个问题,应该是python的问题,创建二维数组要用
dp =[[’’] *(n +1) for _ in range(m+1)]
切不可使用
dp =[[’’] (n +1) ](m+1)
下面创建数组,当m太大的时候会出现bug,最好不要使用

4.数组中未出现的最小正整数

题目

给定一个无序数组arr,找到数组中未出现的最小正整数
例如arr = [-1, 2, 3, 4]。返回1
arr = [1, 2, 3, 4]。返回5
[要求]
时间复杂度为O(n)O(n),空间复杂度为O(1)O(1)
示例1
输入
[-1,2,3,4]
返回值
1

解题思路

1.常规思路
先排序,再找确实值
2.我们先找出数组最小值和最大值的索引,然后计算其最小值到最大值的和
再求出数组和。差值就是缺少的那个正数。如果差值为零证明缺失的是最后的那个整数

核心代码
1.常规思路
class Solution:
    def minNumberdisappered(self, arr):
        if not arr:
            return  0
        # write code here
        m =len(arr)
        num = 0
        arr.sort()
        for i in range(m):
            if arr[i] > 0:
                num += 1
            if arr[i] > num:
                return num

        return arr[-1] + 1
2.符合题意
class Solution:
    def minNumberdisappered(self, arr):
        # write code here
        sum_num = 0
        sum_index = 0
        min_num, max_num = arr[0], arr[0]
        for num in arr:
            sum_num += num
            min_num = min(min_num, num)
            max_num = max(max_num, num)
        for index in range(min_num, max_num + 1):
            sum_index += index
        if sum_index - sum_num == 0:
            return max_num + 1
        else:
            return sum_index - sum_num

5.表达式求值

题目

请写一个整数计算器,支持加减乘三种运算和括号。
示例1
输入
“1+2”
返回值
3

解题思路

算法:栈

  1. 用栈保存各部分计算的和

  2. 遍历表达式,使用 sign 变量记录运算符,初始化是 ‘+’;使用 number 变量记录字符串中的数字部分的数字值是多少
    2.1遇到空格时跳过
    2.2 遇到数字时继续遍历求这个完整的数字的值,保存到 number 中
    2.3 遇到左括号时递归求这个括号里面的表达式的值 先遍历找到对应的右括号,因为可能里面还嵌有多对括号,使用一个变量 counterPartition 统计括号对数直到变量为 0
    2.4 遇到运算符时或者到表达式末尾时,就去计算上一个运算符并把计算结果 push 进栈,然后保存新的运算符到 sign 如果是 + ,不要计算,push 进去 如果是 - ,push 进去负的当前数 如果是 ×、÷ ,pop 出一个运算数和当前数作计算

  3. 最后把栈中的结果求和即可

核心代码
class Solution:

    def solve(self, s):
        # write code here
        stack = []
        sign = '+'
        number = 0
        i = 0
        while i < len(s):
            c = s[i]
            if c == ' ':
                continue
            if c.isdigit():
                number = number * 10 + int(c)
            if c == "(":
                j = i + 1
                counterpatition = 1
                while counterpatition > 0:
                    if s[j] == "(":
                        counterpatition += 1
                    if s[j] == ")":
                        counterpatition -= 1
                    j += 1
                number = self.solve(s[i + 1:j])
                i = j - 1
            if not c.isdigit() or i == len(s) - 1:
                if sign == '+':
                    stack.append(number)
                elif sign == '-':
                    stack.append(-1 * number)
                elif sign == '*':
                    stack.append(stack.pop(-1) * number)
                elif sign == '/':
                    stack.append(stack.pop(-1) / number)
                number = 0
                sign = c
            i += 1
        ans = 0
        while stack:
            ans += stack.pop()
        return ans

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

题目

给定一个链表,请判断该链表是否为回文结构。
示例1
输入
[1,2,2,1]
返回值
true

解题思路

1.思路一
遍历链表,将链表的值存储在数组或者字符串,转为判断字符串或者数组是否为回文结构
2.思路二
找到链表的中间节点,将链表后半段反转,再入链表前半段做对比

核心代码

思路一

class Solution:
    def isPail(self , head ):
        # write code here
        if not head:
            return True
        stack=[]
        while head:
            stack.append(head.val)
            head =head.next
        len_stack = len(stack)
        mid = len_stack//2
        for i in range(mid):
            if stack[i]!= stack[len_stack-i-1]:
                return False
        return True

思路二

class Solution:
    def isPail(self , head ):
        # write code here
        if head == None or head.next == None: return True
        slow,fast = head,head#慢指针、快指针
        #找到中间节点
        while fast != None and fast.next != None:
            fast = fast.next.next
            slow = slow.next
        #找到中间节点后让fast指针指向slow->next;
        fast = slow.next
        slow.next = None
        newList = None
        #进行后半部分的翻转
        while fast != None:
            newList = fast.next
            fast.next = slow
            slow = fast
            fast = newList
        #判断回文
        newList = slow
        fast = head
        while fast != None and newList != None:
            if fast.val != newList.val:return False
            fast = fast.next
            newList = newList.next
        return True
            
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值