牛客网刷题7(python)

  • Post author:
  • Post category:python

36.输入两个链表,找出它们的第一个公共结点。

思路 :建立一个list列表。遍历第一个链表,将其结点值保存在新建列表。同时遍历第二个链表,判断,若链表2中存在结点值属于新建列表,则返回;否则,结点指向下一个值,继续遍历。

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        list = []
        node1 = pHead1
        node2 = pHead2
        while node1:
            list.append(node1.val)
            node1 = node1.next
        while node2:
            if node2 in list:
                return node2
            esle:
                node2 = node2.next

37.统计一个数字在排序数组中出现的次数。

方法1:赖皮写法,直接使用python内置的函数

class Solution:
    def GetNumberOfK(self, data, k):
        # write code here
        return data.count(k)

方法2:计数

class Solution:
    def GetNumberOfK(self,data,k)
        i = 0
        for j in range(len(data)):
            if data[j] == k:
                i += 1
        return i

方法3:二分查找

class Solution:
    def GetNumberOfK(self, data, k):
        # write code here
        def BiSearch(data, k):
            L = len(data)
            if L == 0:
                return 0
            if L == 1 and data[0] == k:
                return 1
            mid = L >> 1
            if data[mid] == k:
                return 1 + BiSearch(data[:mid],k) + BiSearch(data[mid+1:],k)
            elif data[mid] < k:
                return BiSearch(data[mid+1:],k)
            elif data[mid] > k:
                return BiSearch(data[:mid],k)
        return BiSearch(data,k)

38.输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

方法1:递归写法

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def TreeDepth(self, pRoot):
        if not pRoot:
            return 0
        return max(self.TreeDepth(pRoot.left), self.TreeDepth(pRoot.right))+1

方法2:非递归写法,利用循环,层次遍历。建立两个列表:a,b以及一个计数器d。b用来存储单个结点的左右孩子结点,然后将b的值赋给a,每次循环之前都清空b的值。

#利用循环,层次遍历
class Solution:
    def TreeDepth(self, pRoot):
        # write code here
        if not pRoot:
            return 0
        a=[pRoot]
        d=0
        
        while a:
            b = []
            for node in a:
                if node.left:
                    b.append(node.left)
                if node.right:
                    b.append(node.right)
            a=b
            d=d+1
        return d

39.输入一棵二叉树,判断该二叉树是否是平衡二叉树。

平衡二叉树(AVL树)特点:1.二叉排序树,结点的值大于左孩子小于右孩子 2.每一个节点的左孩子和右孩子深度差至多为1

class Solution:
    def IsBalanced_Solution(self, pRoot):
        # write code here
        if pRoot == None:
            return True
        if abs(self.TreeDepth(pRoot.left)-self.TreeDepth(pRoot.right)) > 1:
            return False
        return self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)
       
    def TreeDepth(self, pRoot):
        # write code here
        if pRoot == None:
            return 0
        nLeft = self.TreeDepth(pRoot.left)
        nRight = self.TreeDepth(pRoot.right)
        return max(nLeft+1,nRight+1)#(nLeft+1 if nLeft > nRight else nRight +1)

40.一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

思路:新建一个列表然后进行判定。若列表中不存在数组某元素,则将其添加入列表,否则从列表中删除。

class Solution:
    # 返回[a,b] 其中ab是出现一次的两个数字
    def FindNumsAppearOnce(self, array):
        # write code here
        temp = []
        for i in array:
            if i in temp:
                temp.remove(i)
            else:
                temp.append(i)
        return temp

41.小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

class Solution:
    def FindContinuousSequence(self, tsum):
        # write code here
        res = []
        for i in range(1,tsum/2+1):
            for j in range(i,tsum/2+2):
                temp = (j+i)*(j-i+1)/2
                if temp > tsum:
                    break
                elif temp == tsum:
                    res.append(range(i,j+1))
        return res

42.输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

class Solution:
    def FindNumbersWithSum(self, array, tsum):
        #两个数离得越远则乘积越小
        # write code here
        l = []
        for x in array:
            l.append(tsum-x)
        for y in l:
            if y in array:
                return [tsum-y,y]
        return []

43.汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!

方法:字符串切片拼接

class Solution:
    def LeftRotateString(self, s, n):
        # write code here
        return s[n:]+s[:n]

44.牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

class Solution:
    def ReverseSentence(self, s):
        # write code here
        l = s.split(' ')
        return ' '.join(l[::-1])

45.LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子…..LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。

判断条件:1。除0外没有重复的数字 2.max – min < 5

# -*- coding:utf-8 -*-
class Solution:
    def IsContinuous(self, numbers):
        # write code here
        if not numbers:
            return False
        numbers.sort()
        while 0 in numbers:
            numbers.remove(0)
        if len(numbers) == 1:
            return True
        for j in numbers:
            if numbers.count(j) > 1:
                return False
        if numbers[-1] - numbers[0] < 5:
            return True
        else:
            return False

46.每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数….这样下去….直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)

思路:n个小朋友坐一圈,则喊到m-1的那个小朋友在圈中的位置为(m-1)%n。由于出去一个小朋友后,从下一个小朋友开始喊起,假设第二个出去的小朋友的位置为i,则 i = (m-1+i)%len(n)。

class Solution:
    def LastRemaining_Solution(self, n, m):
        # write code here
        if not m or not n:
            return -1
        res = range(n)
        i = 0
        while len(res) > 1:
            i = (m-1+i)%len(res)
            res.pop(i)
        return res[0]

47.求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

方法1:短路递归

class Solution:
    def Sum_Solution(self, n):
        # write code here
        sum = n
        temp = n and self.Sum_Solution(n-1)
        sum = sum + temp
        return sum

方法2:流氓写法,使用python内置函数

class Solution:
    def Sum_Solution(self, n):
        # write code here
        L = list(range(1,n+1))
        return sum(L)

48.写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

class Solution:
    def Add(self, num1, num2):
        # write code here
        l = []
        l.append(num1)
        l.append(num2)
        return sum(l)

49.将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。

class Solution:
    def StrToInt(self, s):
        # write code here
        numlist=['0','1','2','3','4','5','6','7','8','9','+','-']
        sum=0
        label=1#正负数标记
        if s=='':
            return 0
        for string in s:
            if string in numlist:#如果是合法字符
                if string=='+':
                    label=1
                    continue
                if string=='-':
                    label=-1
                    continue
                else:
                    sum=sum*10+numlist.index(string)
            if string not in numlist:#非合法字符
                sum=0
                break#跳出循环
        return sum*label

50.在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

思路:1.循环扫描数组中每个数,首先判断n[i] == i ?

           2.若等于,则 i+=1,继续扫描下一个数;若不等于则交换n[i] 与n[n[i]]的值。,

           3.上一步的做法是使整个数组从小到大排序。所以继续扫描的话,数组前面满足n[i] == i

           4.若继续扫描出现了 n[m] == i(m>i),即n[m] == n[i],则找到了重复的数。

class Solution:
    # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
    # 函数返回True/False
    def duplicate(self, numbers, duplication):
        # write code here
        cur = 0
        while cur < len(numbers):
            if numbers[cur] == cur:
                cur += 1
                continue                
            if numbers[cur] == numbers[numbers[cur]]:
                duplication[0] = numbers[cur]
                return True
            # 注意这里不能直接multiple assignment
            temp = numbers[cur]
            numbers[cur] = numbers[numbers[cur]]
            numbers[temp] = temp
        return False

 


版权声明:本文为Zz8474原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。