LintCode题解【Python版】

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/feng_zhiyu/article/details/82670162

个人博客:个人博客

目录

前言

入门题

37. 反转一个3位整数

145. 大小写转换

452. 删除链表中的元素

454. 矩阵面积

463. 整数排序

466. 链表节点计数

479. 数组第二大数

484. 交换数组两个元素

763. 进制转换

632. 二叉树的最大节点

简单题

1. A + B 问题

2. 尾部的零

6. 合并排序数组 II

8. 旋转字符串

9. Fizz Buzz 问题

13. 字符串查找

14. 二分查找

22. 平面列表


前言

这里是使用Python刷题,后面也会刷LeetCode(Python),熟悉运用【有兴趣的可以一起】。 会持续更新,有问题或者更好的方法可以提出交流,谢谢。

入门题

37. 反转一个3位整数

反转一个只有3位数的整数。

样例

123 反转之后是 321
900 反转之后是 9

注意事项

你可以假设输入一定是一个只有三位数的整数,这个整数大于等于100,小于1000。

注意:Python3中整除要用 //

class Solution:
    """
    @param number: A 3-digit number.
    @return: Reversed number.
    """

    def reverseInteger(self, number):
        # write your code here
        return number % 10 * 100 + number // 10 % 10 * 10 + number // 100 % 10

if __name__ == '__main__':
    sol = Solution()
    ans = sol.reverseInteger(123)
    print(ans)

简化:利用str的切片操作

class Solution:
    """
    @param number: A 3-digit number.
    @return: Reversed number.
    """

    def reverseInteger(self, number):
        # write your code here
        if number < 0:
            return int(str(number*-1)[::-1])*-1
        return int(str(number)[::-1])

145. 大小写转换

将一个字符由小写字母转换为大写字母

样例

a -> A

b -> B

class Solution:
    """
    @param character: a character
    @return: a character
    """
    ''' s.upper(), s.lower(), s.capitalize():首字母大写,其余小写, s.title():所有单词首字母大写,其余小写 '''
    def lowercaseToUppercase(self, character):
        # write your code here
        return character.upper()

452. 删除链表中的元素

删除链表中等于给定值val的所有节点。

样例

给出链表 1->2->3->3->4->5->3, 和 val = 3, 你需要返回删除3之后的链表:1->2->4->5

思路:链表的建立与遍历,节点的删除操作。 题目中隐含着 可能所有节点都等于val这一情况,所以要新增一个头结点


"""
Definition of ListNode
class ListNode(object):
    def __init__(self, val, next=None):
        self.val = val
        self.next = next
"""

class Solution:
    """
    @param head: a ListNode
    @param val: An integer
    @return: a ListNode
    """

    def removeElements(self, head, val):
        # write your code here
        if head is None:
            return None
        # 可能链表中的元素值都为val,所以新增一个头结点 
        new = ListNode(0)
        new.next = head     # 将原链表接在新链表后面
        pre = new           # pre保存的是有效节点的前一个节点
        while pre.next is not None: # 遍历链表
            if pre.next.val == val: # 值相同
                pre.next = pre.next.next    # 删除该节点
            else:                   # 值不同
                pre = pre.next              # 后移
        return new.next                     # 去掉头结点

454. 矩阵面积

实现一个矩阵类Rectangle,包含如下的一些成员变量与函数:

  1. 两个共有的成员变量 width 和 height 分别代表宽度和高度。

  2. 一个构造函数,接受2个参数 width 和 height 来设定矩阵的宽度和高度。

  3. 一个成员函数 getArea,返回这个矩阵的面积。

样例

Java:
    Rectangle rec = new Rectangle(3, 4);
    rec.getArea(); // should get 12

Python:
    rec = Rectangle(3, 4)
    rec.getArea()
class Rectangle:
    '''
     * Define a constructor which expects two parameters width and height here.
    '''

    # write your code here
    def __init__(self, width, height):
        self.width = width
        self.height = height

    '''
     * Define a public method `getArea` which can calculate the area of the
     * rectangle and return.
    '''

    # write your code here
    def getArea(self):
        return self.height * self.width


if __name__ == '__main__':
    rec = Rectangle(3, 4)
    ans = rec.getArea()
    print(ans)

463. 整数排序

给一组整数,按照升序排序,使用选择排序,冒泡排序,插入排序或者任何 O(n2) 的排序算法。

样例

对于数组 [3, 2, 1, 4, 5], 排序后为:[1, 2, 3, 4, 5]

class Solution:
    """
    @param A: an integer array
    @return: nothing
    """

    def sortIntegers(self, A):
        # write your code here
        # 101ms
        # A.sort() # 快速排序
        # 302ms
        # for i in range(len(A)):
        #     for j in range(i):
        #         if (A[i] < A[j]):
        #             A[i], A[j] = A[j], A[i]
        # 402ms 冒泡排序
        # for i in range(len(A) - 1):
        #     for j in range(len(A) - i - 1):
        #         if (A[j] > A[j + 1]):
        #             A[j], A[j + 1] = A[j + 1], A[j]
        # 251ms 选择排序
        # for i in range(len(A)):
        #     key = i
        #     for j in range(i, len(A)):
        #         if (A[j] < A[key]):
        #             key = j
        #     A[i], A[key] = A[key], A[i]
        # 201ms 插入排序
        for i in range(1, len(A)):
            tmp = A[i]
            for j in range(i, -1, -1):
                # j为当前位置,试探j-1位置
                if A[j-1] > tmp:
                    A[j] = A[j-1]
                else:
                    break
            A[j] = tmp


if __name__ == '__main__':
    A = [3, 2, 1, 4, 5]
    Solution().sortIntegers(A)
    print(A)

466. 链表节点计数

计算链表中有多少个节点.

样例

给出 1->3->5, 返回 3.

"""
Definition of ListNode
class ListNode(object):
    def __init__(self, val, next=None):
        self.val = val
        self.next = next
"""

class Solution:
    """
    @param head: the first node of linked list.
    @return: An integer
    """
    def countNodes(self, head):
        # write your code here
        cnt = 0
        while head is not None:
            cnt += 1
            head = head.next
        return cnt

479. 数组第二大数

在数组中找到第二大的数

样例

给出 [1, 3, 2, 4], 返回 3.

给出 [1, 2], 返回 1.

注意事项

你可以假定至少有两个数字

class Solution:
    """
    @param nums: An integer array
    @return: The second max number in the array.
    """
    def secondMax(self, nums):
        # write your code here
        nums.sort()
        return nums[len(nums)-2]

484. 交换数组两个元素

给你一个数组和两个索引,交换下标为这两个索引的数字

样例

给出 [1,2,3,4] index1 = 2, index2 = 3. 交换之后变成 [1,2,4,3]

class Solution:
    """
    @param A: An integer array
    @param index1: the first index
    @param index2: the second index
    @return: nothing
    """
    def swapIntegers(self, A, index1, index2):
        # write your code here
        A[index1], A[index2] = A[index2], A[index1]

763. 进制转换

给定一个十进制数 n 和 一个整数 k, 将 十进制数 n 转换成 k进制数.

样例

样例 1:
给定 n = 5k = 2
return "101"

样例 2:
给定 n = 30k = 16
return "1E"

注意事项

1.0<=n<=2^31-12<=k<=16
2.每个大于 9 的字符都用大写字母表示

注意:n==0情形

# -*- coding: utf-8 -*-
# @Time    : 18-9-12 下午11:12
# @Author  : yufeng
# @Blog    :https://blog.csdn.net/feng_zhiyu

class Solution:
    """
    @param n: a decimal number
    @param k: a Integer represent base-k
    @return: a base-k number
    """
    # 151ms
    def hexConversion(self, n, k):
        # write your code here
        jin = ['A', 'B', 'C', 'D', 'E', 'F']
        ans = []
        if n == 0:
            ans.append('0')
        while n != 0:
            c = n % k
            n //= k
            if c > 9:
                ans.append(jin[c-10])
            else:
                ans.append(str(c))
        s = "".join(ans)
        return s[::-1]


if __name__ == '__main__':
    ans = Solution().hexConversion(30, 16)
    print(ans)

632. 二叉树的最大节点

在二叉树中寻找值最大的节点并返回。

样例

给出如下一棵二叉树:

     1
   /   \
 -5     2
 / \   /  \
0   3 -4  -5 

返回值为 3 的节点。

"""
Definition of TreeNode:
class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left, self.right = None, None
"""


class Solution:
    """
    @param: root: the root of tree
    @return: the max node
    """
    node = None
    maxNum = -99999

    def maxNode(self, root):
        # write your code here
        if root is None:
            return None
        self.max(root)
        return self.node

    def max(self, root):
        if root is None:
            return None
        if root.val > self.maxNum:
            self.maxNum = root.val
            self.node = root
        self.max(root.left)
        self.max(root.right)

简单题

1. A + B 问题

给出两个整数 aa 和 bb , 求他们的和。

样例

如果 a=1 并且 b=2,返回3

挑战

显然你可以直接 return a + b,但是你是否可以挑战一下不这样做?(不使用++等算数运算符)

说明

a和b都是 32位 整数么?

  • 是的

我可以使用位运算符么?

  • 当然可以

注意事项

你不需要从输入流读入数据,只需要根据aplusb的两个参数a和b,计算他们的和并返回就行。

思路:

# x^y                执行加法
# (x&y)<<1           进位操作

Python3中long 类型存放数据无限长,当正整数+负整数时,不会出现溢出。 

因此会超时。 详解见:不用加减乘除做加法中Python存在的bug

67%正确:

class Solution:
    """
    @param a: An integer
    @param b: An integer
    @return: The sum of a and b
    """

    # x^y                执行加法
    # (x&y)<<1           进位操作
    def aplusb(self, a, b):
        # if (a&b) == 0:
        #     return a|b
        # return self.aplusb((a & b) << 1, a ^ b)
        sum = a ^ b
        carry = (a & b) << 1
        while (carry):
            a = sum
            b = carry
            sum = a ^ b
            carry = (a & b) << 1
            # print(sum, end="")
        return sum

2. 尾部的零

设计一个算法,计算出n阶乘中尾部零的个数

样例

11! = 39916800,因此应该返回 2

挑战

O(logN)的时间复杂度

思路:10=2*5;求n!十进制数尾部0的个数看因子2和因子5的倍数的个数,但是5的倍数的个数一定小于2的倍数的个数。

类似地,求三进制就是n//=3,二进制n//=2

class Solution:
    """
    @param: n: An integer
    @return: An integer, denote the number of trailing zeros in n!
    """
    def trailingZeros(self, n):
        # write your code here, try to do it without arithmetic operators.
        res = 0
        while(n):
            n //= 5
            res += n
        return res

6. 合并排序数组 II

合并两个排序的整数数组A和B变成一个新的数组。

样例

给出A=[1,2,3,4],B=[2,4,5,6],返回 [1,2,2,3,4,4,5,6]

挑战

你能否优化你的算法,如果其中一个数组很大而另一个数组很小?

class Solution:
    """
    @param A: sorted integer array A
    @param B: sorted integer array B
    @return: A new sorted integer array
    """

    def mergeSortedArray(self, A, B):
        # write your code here
        # 101ms
        # if A is None:
        #     return B
        # if B is None:
        #     return A
        # i = 0
        # if (len(A) > len(B)):
        #     big, small = A, B
        # else:
        #     big, small = B, A
        # while (len(small)):
        #     tmp = small[0]
        #     j = len(big)
        #     if (i == j):
        #         big.append(tmp)
        #         small.remove(tmp)
        #     elif tmp <= big[i]:
        #         big.insert(i, tmp)
        #         small.remove(tmp)
        #     else:
        #         i += 1
        # return big
        
        # 151ms
        C=A+B
        C.sort(reverse = False)
        return C

8. 旋转字符串

给定一个字符串和一个偏移量,根据偏移量旋转字符串(从左向右旋转)

样例

对于字符串 "abcdefg".

offset=0 => "abcdefg"
offset=1 => "gabcdef"
offset=2 => "fgabcde"
offset=3 => "efgabcd"

挑战

在数组上原地旋转,使用O(1)的额外空间

分析:这里str是array类型, 你可以通过help(array)查看到内置函数insert(), pop() 和list用法类似。

python中 array模块学习笔记

class Solution:
    """
    @param str: An array of char
    @param offset: An integer
    @return: nothing
    """

    def rotateString(self, str, offset):
        # write your code here
        if not str or not offset:
            return
        for i in range(offset % len(str)):
            str.insert(0, str.pop())


if __name__ == '__main__':
    s = 'a,b,c,d,e,f,g'
    str = s.split(',')
    Solution().rotateString(str, 3)
    print(str)

9. Fizz Buzz 问题

给你一个整数n. 从 1 到 n 按照下面的规则打印每个数:

  • 如果这个数被3整除,打印fizz.
  • 如果这个数被5整除,打印buzz.
  • 如果这个数能同时被35整除,打印fizz buzz.

样例

比如 n = 15, 返回一个字符串数组:

[
  "1", "2", "fizz",
  "4", "buzz", "fizz",
  "7", "8", "fizz",
  "buzz", "11", "fizz",
  "13", "14", "fizz buzz"
]

挑战

Can you do it with only one if statement?

输入测试数据 (每行一个参数)

class Solution:
    """
    @param n: An integer
    @return: A list of strings.
    """

    def fizzBuzz(self, n):
        # write your code here
        res = []
        for i in range(1, n + 1):
            if i % 15 == 0:
                res.append("fizz buzz")
            elif i % 3 == 0:
                res.append("fizz")
            elif i % 5 == 0:
                res.append("buzz")
            else:
                res.append(str(i))
        return res

13. 字符串查找

对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回 -1

样例

如果 source = "source" 和 target = "target",返回 -1

如果 source = "abcdabcdefg" 和 target = "bcd",返回 1

挑战

O(n2)的算法是可以接受的。如果你能用O(n)的算法做出来那更加好。(提示:KMP)

说明

在面试中我是否需要实现KMP算法?

  • 不需要,当这种问题出现在面试中时,面试官很可能只是想要测试一下你的基础应用能力。当然你需要先跟面试官确认清楚要怎么实现这个题。
class Solution:
    """
    @param source:
    @param target:
    @return: return the index
    """
    def strStr(self, source, target):
        if source is None or target is None:
            return -1
        len_s = len(source)
        len_t = len(target)
        for i in range(len_s - len_t + 1):
            j = 0
            while (j < len_t):
                if source[i + j] != target[j]:
                    break
                j += 1
            if j == len_t:
                return i
        return -1

字符串匹配的kmp算法 及 python实现

14. 二分查找

给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1

样例

在数组 [1, 2, 3, 3, 4, 5, 10] 中二分查找3,返回2

挑战

如果数组中的整数个数超过了2^32,你的算法是否会出错?

class Solution:
    """
    @param nums: The integer array.
    @param target: Target to find.
    @return: The first position of target. Position starts from 0.
    """
    # 101ms
    def binarySearch(self, nums, target):
        # write your code here
        l, r=0, len(nums) - 1
        while l <= r:
            mid = (l + r) >> 1
            if nums[mid] < target:
                l = mid + 1
            elif nums[mid] > target:
                r = mid - 1
            else:
                while nums[mid] == target:
                    mid -= 1
                return mid+1
        return -1

22. 平面列表

给定一个列表,该列表中的每个要素要么是个列表,要么是整数。将其变成一个只包含整数的简单列表。

样例

给定 [1,2,[1,2]],返回 [1,2,1,2]

给定 [4,[3,[2,[1]]]],返回 [4,3,2,1]

挑战

请用非递归方法尝试解答这道题。

注意事项

如果给定的列表中的要素本身也是一个列表,那么它也可以包含列表。

分析:python的type和isinstance的区别 非递归可以用栈实现

  • isinstance(object,type)判断一个对象是否是已知类型type,其中type()作用类似,有区别,详见上面链接
  • list.extend(seq) 用新列表扩展原来的列表

递归:

class Solution(object):
    # @param nestedList a list, each element in the list
    # can be a list or integer, for example [1,2,[1,2]]
    # @return {int[]} a list of integer
    def flatten(self, nestedList):
        # Write your code here
        if isinstance(nestedList,int):# isinstance(object,type)
            return [nestedList]
        res = []
        for i in nestedList:
            res.extend(self.flatten(i))# list.extend(seq) 用新列表扩展原来的列表
        return res

非递归(这种效率最高):

class Solution(object):
    # @param nestedList a list, each element in the list
    # can be a list or integer, for example [1,2,[1,2]]
    # @return {int[]} a list of integer
    def flatten(self, nestedList):
        # Write your code here
        stack = [nestedList]
        res = []
        while stack:
            top = stack.pop()
            if isinstance(top, list):
                for elem in reversed(top):  # 栈的特点需要反转
                    stack.append(elem)
            else:
                res.append(top)
        return res

另一种来自讨论区(效率其次):

class Solution(object):
    # @param nestedList a list, each element in the list
    # can be a list or integer, for example [1,2,[1,2]]
    # @return {int[]} a list of integer
    def flatten(self, nestedList):
        # Write your code here
        if isinstance(nestedList, int):
            return [nestedList]
        
        ret = []
        while len(nestedList) > 0:
            current = nestedList.pop(0)
            if isinstance(current, int):
                ret.append(current)
            else:
                nestedList = current + nestedList
        return ret

猜你喜欢

转载自blog.csdn.net/feng_zhiyu/article/details/82670162