zoukankan      html  css  js  c++  java
  • leetcode 004-006

    这几天疯狂考试,具体的代码思路就不分析了,第四第五题都用自己的方法实现了,因为是暴力刚,被卡边界的过程挺惨的。说起来,这就是有思路和没思路的区别了。

    更新:考完试,想起来还欠着这个。把之前没注意的都补上

    leetcode 004

    代码实现

    class Solution:
        
        def delBothArrays(self, lst_nums, del_len):
            """
            :type lst_nums: list[list[int]]
            :type del_len: int
            :rtype: list[int]
            """
            nums1, nums2 = lst_nums
            for t in range(del_len):
                if len(nums1) == 0:
                    nums2.pop()
                elif len(nums2) == 0:
                    nums1.pop()
                else:
                    if nums1[-1] >= nums2[-1]:
                        nums1.pop()
                    else:
                        nums2.pop()
        
        def singleLstMedian(self, nums):
            """
            :type nums: List[int]
            :rtype: float
            """
            if len(nums) % 2:
                i = (len(nums)-1) // 2
                return nums[i]
            else:
                i = (len(nums)-2) // 2
                return (nums[i] + nums[i+1]) / 2
        
        def findMedianSortedArrays(self, nums1, nums2):
            """
            :type nums1: List[int]
            :type nums2: List[int]
            :rtype: float
            """
            i = len(nums1) - 1
            j = len(nums2) - 1
            if i == -1:
                return self.singleLstMedian(nums2)
            elif j == -1:
                return self.singleLstMedian(nums1)
            if (i + j) % 2:
                del_len = (i + j + 1) // 2
                self.delBothArrays([nums1,nums2], del_len)
                if len(nums1) == 0:
                    median = nums2[-1]
                elif len(nums2) == 0:
                    median = nums1[-1]
                else:
                    median = nums1[-1] if nums1[-1] >= nums2[-1] else nums2[-1]
            else:
                del_len = (i + j) // 2
                self.delBothArrays([nums1,nums2], del_len)
                if len(nums1) == 1:
                    lst_new = nums1[-1:] + nums2[-2:]
                elif len(nums2) == 1:
                    lst_new = nums1[-2:] + nums2[-1:]
                else:
                    lst_new = nums1[-2:] + nums2[-2:]
                lst_new.sort()
                median = (lst_new[-1] + lst_new[-2]) / 2
            return median
    

    上面是我自己的思路,简单来说就是将两个数组共同从后向前删去一半(或减一的一半)的数。需要注意的是,我这两个数组并没有合并。删完之后的两个数组,就会暴露出两个疑似中位数的值,最后比较出来就可以了。时间复杂度是O(m+n)。

    而解答里的思路,怎么说非常的巧妙。具体的思路如下:

    只需要保证 B[j-1]<A[i] 和 A[i-1]<B[j] ,就有max(left) < min(right)。同时 i 的检索使用了二分技巧,而 j 由 len(left) = len(right) 可以找到一个计算式:(j = frac{}m+n+1{2}-1)。需要注意的是,+1是非常重要的,这在总数为奇的情况下,会保证左边那堆数永远比右边的多一个。

    解答代码如下:

    class Solution:
        def findMedianSortedArrays(self, nums1, nums2):
            """
            :type nums1: List[int]
            :type nums2: List[int]
            :rtype: float
            """
            m, n = len(nums1), len(nums2)
            if m > n:
                m, n, nums1, nums2 = n, m, nums2, nums1
            imin, imax, half_len = 0, m, (m + n + 1) // 2
            while imin <= imax:
                i = (imin + imax) // 2
                j = half_len - i
                if i > 0 and nums1[i-1] > nums2[j]:
                    imax = i - 1
                elif i < m and nums2[j-1] > nums1[i]:
                    imin = i + 1
                else:
                    if i == 0: max_left = nums2[j-1]
                    elif j == 0: max_left = nums1[i-1]
                    else: max_left = max(nums1[i-1], nums2[j-1])
                    
                    if (m + n) % 2 == 1:
                        return max_left
                    
                    if i == m: min_right = nums2[j]
                    elif j == n: min_right = nums1[i]
                    else: min_right = min(nums1[i], nums2[j])
                        
                    return (max_left + min_right) / 2
    

    leetcode 005

    代码实现

    class Solution:
        def longestPalindrome(self, s):
            """
            :type s: str
            :rtype: str
            """
            if len(s) == 0 or len(s) == 1:
                return s
            lst_init = list(s)
            lst_cmp = []
            length = 0
            pos = 1
            is_odd = True
            pop_num = lst_init.pop()
            for i in range(len(s) - 1, 0, -1):
                lst_cmp.append(pop_num)
                offset = 1
                while True:     # 找出偶回文串
                    if len(lst_cmp) < offset or len(lst_init) < offset:
                        break
                    if lst_cmp[-offset] == lst_init[-offset]:
                        if offset > length:
                            length = offset
                            pos = i
                            is_odd = False
                        offset += 1
                    else:
                        break
                pop_num = lst_init.pop()
                offset = 1
                while True:     # 找出奇回文串
                    if len(lst_cmp) < offset or len(lst_init) < offset:
                        break
                    if lst_cmp[-offset] == lst_init[-offset]:
                        if offset >= length: # 奇大于偶,但会导致不稳定
                            length = offset
                            pos = i
                            is_odd = True
                        offset += 1
                    else:
                        break
            if not is_odd:
                right = pos + length
                left = pos - length
            else:
                if length == 0:
                    return s[-1]  # 如果不规则,返回最后一个
                right = pos + length
                left = pos - 1 - length
            return s[left:right]
    

    这道题我的解题思路其实是挺清晰的,简而言之就是用两个队列并排比较。代码看起来很复杂,其实时间复杂度为O(n^2),空间复杂度为O(n),算是还好。做的时候确实被很多边界卡得很厉害,等以后看看有没有办法简化。

    看了下答案,竟然有三四种解法,之后一个个去琢磨。

    leetcode 006

    代码实现

    这道题没有做出来。

    class Solution:
        def convert(self, s, numRows):
            """
            :type s: str
            :type numRows: int
            :rtype: str
            """
            if numRows == 1 or numRows >= len(s):
                return s
    
            L = [''] * numRows
            index, step = 0, 1
    
            for x in s:
                L[index] += x
                if index == 0:
                    step = 1
                elif index == numRows -1:
                    step = -1
                index += step
    
            return ''.join(L)
    
  • 相关阅读:
    Hystrix高可用系统容错框架,资源隔离,熔断,限流
    Leecode no.25 K 个一组翻转链表
    no.1 Web浏览器
    源码解析-JavaNIO之Buffer,Channel
    Leecode no.24 两两交换链表中的节点
    Kafka RocketMQ 是推还是拉?
    Leecode no.23 合并K个升序链表
    图解计算机底层IO过程及JavaNIO
    Leecode no.21 合并两个有序链表
    AcWing每日一题--摘花生
  • 原文地址:https://www.cnblogs.com/ChanWunsam/p/10230411.html
Copyright © 2011-2022 走看看