leetcode-腾讯算法笔试题

数组和字符串:

两数之和:给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

代码:

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        for i in range(len(nums)):
            number = target - nums[i]
            for j in range(i + 1, len(nums)):
                if nums[j] == number:
                    return [i, j]

两个排序数组的中位数:给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 

请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log (m+n)) 。

你可以假设 nums1 和 nums2 不同时为空。

代码:

def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        length1 = len(nums1)
        length2 = len(nums2)
        total = length1 + length2
        if total % 2 == 0:
            half = total / 2 - 1 
        else:
            half = total / 2
        res_list = []
        while len(nums1) and len(nums2):
            if nums1[0] < nums2[0]:
                res_list.append(nums1.pop(0))
            else:
                res_list.append(nums2.pop(0))
        if len(nums1):
            res_list += nums1
        elif len(nums2):
            res_list += nums2
        
        if total % 2 == 0:
            return (res_list[half] + res_list[half + 1]) / 2.
        else:
            return res_list[half]

最长回文子串:给定一个字符串 s,找到 s 中最长的回文子串。

你可以假设 的最大长度为1000。

代码:

def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        # edge case
        if len(s) == 0:
            return s
        if len(s) == 1:
            return s[0]
        # init result
        result = ""
        for i in range(0, len(s) - 1):
            tmp = self.helper(s, i, i)  # odd case
            if len(result) < len(tmp):
                result = tmp
            tmp = self.helper(s, i, i + 1)  # even case
            if len(result) < len(tmp):
                result = tmp
        return result

    def helper(self, s, i, j):
        r = i
        c = j
        tmp = ""
        while s[r] == s[c]:
            if r != c:
                tmp = s[r] + tmp + s[c]
            else:
                tmp = s[r]   #odd case
            r = r - 1
            c = c + 1
            if r < 0 or c > len(s) - 1:
                return tmp
        return tmp

链表突击:

反转链表:反转一个单链表。

代码:

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if head is None or head.next is None:
            return head
        pre = None
        cur = head
        h = head
        while cur:
            h = cur
            tmp = cur.next
            cur.next = pre
            pre = cur
            cur = tmp
        return h

两数相加:

给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。

将两数相加返回一个新的链表。你可以假设除了数字 0 之外,这两个数字都不会以零开头。

代码:

class Solution(object):
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        add = 0
        sum_result = ListNode(0)
        head = sum_result
        while l1 or l2 or add:
            val = (l1.val if l1 else 0) + (l2.val if l2 else 0) + add 
            sum_result.val = val % 10
            add = val / 10

            l1 = l1.next if l1 else None
            l2 = l2.next if l2 else None
            
            if l1 or l2 or add:
                sum_result.next = ListNode(add)
                sum_result = sum_result.next

        return head

合并两个有序链表:将两个有序链表合并

为一个新的有序链表并返回。新链表是通过

拼接给定的两个链表的所有节点组成的。 

代码:

class Solution(object):
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        head = ListNode(0)
        cur = head
        while l1 and l2:
            if l1.val <= l2.val: 
                cur.next = ListNode(l1.val)
                l1 = l1.next
            else:
                cur.next = ListNode(l2.val)
                l2 = l2.next
            cur = cur.next
        
        if l1:
            cur.next = l1
        if l2:
            cur.next = l2
        return head.next

数字与数学:

反转整数:给定一个 32 位有符号整数,将整数中的数字进行反转。

代码:

 def reverse(self, x):
        """
        :type x: int
        :rtype: int
        """
        flag = 1
        if x < 0:
            flag = -1
        number = flag * x
        result = 0
        while number:
            result = result * 10 + number % 10
            number = number / 10
        if flag*result < -2**31 or flag*result > 2**31 - 1:
            return 0
        else:
            return flag*result

回文数:判断一个整数是否是回文数。

回文数是指正序(从左向右)和倒序

(从右向左)读都是一样的整数。

代码:

def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        str_x = str(x)
        if str_x[-1::-1] == str_x:
            return True
        return False

只出现一次的数字:给定一个非空整数数组,

除了某个元素只出现一次以外,其余每个元素

均出现两次。找出那个只出现了一次的元素。

代码:

def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) == 1:
            return nums[0]
        
        sorted_nums = sorted(nums)
        for i in range(len(sorted_nums) / 2):
            if sorted_nums[2 * i] != sorted_nums[2 * i + 1]:
                return sorted_nums[2 * i]
        
        return sorted_nums[-1]

排序与搜索:

只出现一次的数字:给定一个非空整数数组,除了某个元素

只出现一次以外,其余每个元素均出现两次。

找出那个只出现了一次的元素。

代码:

def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) == 1:
            return nums[0]
        
        sorted_nums = sorted(nums)
        for i in range(len(sorted_nums) / 2):
            if sorted_nums[2 * i] != sorted_nums[2 * i + 1]:
                return sorted_nums[2 * i]
        
        return sorted_nums[-1]

搜索旋转排序数组:

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。

你可以假设数组中不存在重复的元素。

你的算法时间复杂度必须是 O(log n) 级别。

代码:

def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        l = 0
        r = len(nums) - 1
        while l <= r:
            m = (l + r) // 2
            if nums[m] == target:
                return m
            
            if nums[l] <= nums[m]:
                if nums[l] <= target <= nums[m]:
                    r = m - 1
                else:
                    l = m + 1
            
            else:
                if nums[m] <= target <= nums[r]:
                    l = m + 1
                else:
                    r = m - 1
        return -1

回溯算法:

 括号生成:给出 n 代表生成括号的对数,

请你写出一个函数,使其能够生成所

有可能的并且有效的括号组合。

代码:

def generateParenthesis(self, n):
        """
        :type n: int
        :rtype: List[str]
        """
        result = []
        self.generate("", n, n, result)
        return result
    
    def generate(self, item, left, right, result):
        if left == 0 and right == 0:
            result.append(item)
            return 
        
        if left > 0:
            self.generate(item + "(", left - 1, right, result)
        if left < right:
            self.generate(item + ")", left, right - 1, result)

子集:给定一组不含重复元素的整数数组 nums

返回该数组所有可能的子集(幂集)。

代码:

def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        self.result = []
        self.search(sorted(nums), [], 0)
        return self.result
    
    def search(self, nums, S, index):
        if len(nums) == index:
            self.result.append(S)
            return 
        
        self.search(nums, S + [nums[index]], index + 1)
        self.search(nums, S, index + 1)

动态规划:

爬楼梯:

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。

你有多少种不同的方法可以爬到楼顶呢?

代码:

def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        a = []
        a.append(1)
        a.append(2)
        for i in range(2, n):
            a.append(a[i - 2] + a[i - 1])
        return a[n - 1]

最大子序和:给定一个整数数组 nums ,

找到一个具有最大和的连续子数组(子数组最少包含一个元素),

返回其最大和。

代码:

def maxSubArray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        one_sum = 0
        max_sum = nums[0]
        
        for i in range(len(nums)):
            one_sum += nums[i]
            max_sum = max(max_sum, one_sum)
            if one_sum < 0:
                one_sum = 0
        
        return max_sum

买卖股票的最佳时机:

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

注意你不能在买入股票前卖出股票。

代码:

 def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        self.max_profit = 0
        self.search(prices)
        return self.max_profit
    
    def search(self, prices):
        if len(prices) <= 1:
            return
        mid = len(prices) / 2
        self.max_profit = max(max(prices[mid:]) - min(prices[:mid]), self.max_profit)
        self.search(prices[mid:])
        self.search(prices[:mid])

你可能感兴趣的:(Python)