leetcode python 2-11

说明:自己思考以及和别人对比,参考对比程序来源

包含 2 - 11 题

002、单向链表两数相加

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        current = ListNode(0)
        p = current
        value = 0

        while l1 or l2:

            if l1:
                value = value + l1.val
                l1 = l1.next

            if l2:
                value = value + l2.val
                l2 = l2.next

            # current.var = value % 10
            var = value % 10
            value = value / 10
            current.next = ListNode(var)
            current = current.next

        if value:
            # current.var = value
            current.next = ListNode(value)

        return p.next

if __name__ == '__main__':
    a, a.next, a.next.next = ListNode(2), ListNode(4), ListNode(3)
    b, b.next, b.next.next = ListNode(5), ListNode(6), ListNode(4)
    result = Solution().addTwoNumbers(a, b)
    print "%d -> %d -> %d " %(result.val , result.next.val , result.next.next.val)

这个题主要注意以下问题:要考虑两个链表不同长度的相加;第一个头结点不保留数据,返回p.next;

003、最大不重复的子串

Given "abcabcbb", the answer is "abc", which the length is 3.
Given "bbbbb", the answer is "b", with the length of 1.
Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

以下是自己的答案,用了两个for循环,还是复杂了点,最后一个测试超时
class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        length_max = 0

        for i in range(0,len(s)):
            mystr , length = self.search(s[i:])
            if length > length_max:
                length_max = length
        return length_max



    def search(self,s):
        i = 0
        while s[i] not in s[0:i]:
            i += 1
            if i == len(s):
                break

        length = i
        mystr = s[0:i]
        #print mystr
        return mystr,length


if __name__ == '__main__' :

    s = Solution()
    length_max1 = s.lengthOfLongestSubstring('abcdefgabc')
    print length_max1
别人的答案 48.5%
class Solution:
    # @return an integer
    def lengthOfLongestSubstring(self, s):
        longest, start, visited = 0, 0, [False for _ in xrange(256)]
        for i, char in enumerate(s):
            if visited[ord(char)]:
                while char != s[start]:
                    visited[ord(s[start])] = False
                    start += 1
                start += 1
            else:
                visited[ord(char)] = True
            longest = max(longest, i - start + 1)
        return longest

if __name__ == "__main__":
    print Solution().lengthOfLongestSubstring("abcabcbb")

004、Median of Two Sorted Arrays

There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n))

class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        result = []
        i = 0
        j = 0
        median, flag = (len(nums1) + len(nums2))//2, (len(nums1) + len(nums2))%2
        while i < len(nums1) and j < len(nums2):
            if nums1[i] < nums2[j]:
                result.append(nums1[i])
                i += 1
            else:
                result.append(nums2[j])
                j += 1
        result += nums1[i:]
        result += nums2[j:]
        if flag == 1:
            return (result[median] + result[median]) * 0.5
        if flag == 0:
            return (result[median - 1] + result[median]) * 0.5


if __name__ == '__main__':
    print Solution().findMedianSortedArrays([1, 3, 5, 7], [2, 4, 6])
    print Solution().findMedianSortedArrays([1, 2], [3,4])

这个题目反应出基础功,由于快速过了一遍数据结构和算法,将两个排好序的序列重新组合这么简单的问题居然会无从下手,而又觉得特别熟悉,其实在归并排序中就有出现,而这边也是完全借用归并排序的思想。其实上述有个明显的缺点就是将整个数组排序了,实际上只需要排序到指定位置即可。

运行时间 108ms 超过了60%
class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        len1, len2 = len(nums1), len(nums2)
        if (len1 + len2) % 2 == 1: 
            return self.getKth(nums1, nums2, (len1 + len2)/2 + 1)
        else:
            return (self.getKth(nums1, nums2, (len1 + len2)/2) + \
                    self.getKth(nums1, nums2, (len1 + len2)/2 + 1)) * 0.5

    def getKth(self, A, B, k):
        m, n = len(A), len(B)
        if m > n:
            return self.getKth(B, A, k)

        left, right = 0, m    
        while left < right:
            mid = left + (right - left) / 2
            if 0 <= k - 1 - mid < n and A[mid] >= B[k - 1 - mid]:
                right = mid
            else:
                left = mid + 1

        Ai_minus_1 = A[left - 1] if left - 1 >= 0 else float("-inf")
        Bj = B[k - 1 - left] if k - 1 - left >= 0 else float("-inf")

        return max(Ai_minus_1, Bj)

上述为别人的思路,运行时间95ms。

005 Longest Palindromic Substring 最大回文字符串

Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        length = len(s)
        maxlen, maxL, maxR = 0, 0, 0
        for i in range(length):
            start = i    #考虑为偶数情况
            end = i + 1
            while start >= 0 and end <= length - 1:
                if s[start] == s[end]:
                    if end - start + 1 > maxlen:
                        maxlen = end - start + 1
                        maxL = start
                        maxR = end
                    start -= 1
                    end += 1
                else:
                    break
            start = i - 1   #考虑为奇数情况
            end = i + 1
            while start >= 0 and end <= length - 1:
                if s[start] == s[end]:
                    if end - start + 1 > maxlen:
                        maxlen = end - start + 1
                        maxL = start
                        maxR = end
                    start -= 1
                    end += 1
                else:
                    break
        return s[maxL:maxR+1]
        
if __name__ == '__main__':
    solution = Solution()
    print solution.longestPalindrome('abbacd')

上面的程序运行效率不是很高,只优于41%的提交。
是否能把所有的情况全部转换为奇数处理?Manacher算法,且这个算法求最长回文子串的时间复杂度是线性O(N)的。参考

def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        def preProcess(s):
            if not s:
                return ['^', '$']
            T = ['^']
            for c in s:
                T +=  ['#', c]
            T += ['#', '$']
            return T

        T = preProcess(s)
        P = [0] * len(T) 
        center, right = 0, 0
        for i in xrange(1, len(T) - 1):
            i_mirror = 2 * center - i
            if right > i:
                P[i] = min(right - i, P[i_mirror])
            else:
                P[i] = 0

            while T[i + 1 + P[i]] == T[i - 1 - P[i]]:
                P[i] += 1

            if i + P[i] > right:
                center, right = i, i + P[i]       
        
        max_i = 0
        for i in xrange(1, len(T) - 1):
            if P[i] > P[max_i]:
                max_i = i
        start = (max_i - 1 - P[max_i]) / 2
        return s[start : start + P[max_i]]

6、 ZigZag Conversion

class Solution(object):
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        if numRows == 1:
            return s
        str1 = ''
        j, flag = 0, 0
        T = ['' for i in range(numRows)]

        for i in range(len(s)):
            if flag == 0:
                T[j] += s[i]
                j += 1
                if j == numRows:
                    flag = 1
                    j -= 2
            else:
                #p[i] = j
                T[j] += s[i]
                j -= 1
                if j == -1:
                    flag = 0
                    j += 2

        for i in range(numRows):
            str1 += T[i]
        return str1

if __name__ == '__main__':
    solution = Solution()
    print solution.convert('abc',2)

上述算法 思路主要是:0123432101234321。
运行结果出来一瞬间真是崩了,216ms,只胜于10%,可能原因一是算法确实没别人好,二是字符串操作可能会带来开销。

class Solution(object):
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        if numRows == 1:
            return s
        step, zigzag = 2 * numRows - 2, ""
        for i in xrange(numRows):
            for j in xrange(i, len(s), step):
                zigzag += s[j]
                if 0 < i < numRows - 1 and j + step - 2 * i < len(s):
                    zigzag += s[j + step - 2 * i]
        return zigzag

if __name__ == "__main__":
    print Solution().convert("PAYPALISHIRING", 3)

该算法优于40%,还是不够好

7、Reverse digits of an integer

Example1: x = 123, return 321
Example2: x = -123, return -321

这个问题需要注意的有两个问题,一是可能是负数,二是考虑是否越界,假设为有符号32bit。
反转一般有两种常用解决方式,一是以整数方式,除10取余,二是利用字符串自带的反转功能,str1[::-1]。

class Solution(object):
    def reverse(self, x):  #该方法更优
        """
        :type x: int
        :rtype: int
        """
        if x < 0:
            return -self.reverse(-x)

        result = 0
        while x:
            result = result * 10 + x % 10
            x /= 10
        return result if result <= 0x7fffffff else 0  # Handle overflow.

    def reverse2(self, x):
        """
        :type x: int
        :rtype: int
        """
        if x < 0:
            x = int(str(x)[::-1][-1] + str(x)[::-1][:-1])
        else:
            x = int(str(x)[::-1])
        x = 0 if abs(x) > 0x7FFFFFFF else x
        return x

    def reverse3(self, x):
        """
        :type x: int
        :rtype: int
        """
        s = cmp(x, 0)
        r = int(`s * x`[::-1])
        return s * r * (r < 2 ** 31)

字符串反转有以下两种常用方法:

  • 使用[::-1]:
    s = 'python'
    print s[::-1]

  • 使用reverse()方法:
    l = list(s)
    l.reverse() #不返回,但是原列表已经反转
    print ''.join(l)

8、String to Integer (atoi)

这个题确实有很多细节需要考虑,一开始做的时候只考虑了字符串中间有字母,以及首位可能为'-',发现还有可能首位为‘+’和一个或多个空格。该题还有一个特殊就是'12a'也能出结果12,就是是逐个判断

class Solution(object):
    def myAtoi(self, str):
        """
        :type str: str
        :rtype: int
        """
        result, flag = 0, 1
        if len(str) == 0:
            return 0
        if len(str) == 1 and str not in '0123456789':
            return 0
        if str[0] == ' ':
            return self.myAtoi(str[1:])
        
        for i in range(0,len(str)):
            if i == 0 and str[i] not in '-+0123456789':
                return 0
            if i>0 and str[i] not in '0123456789':
                return 0
        
        for c in str:            
            if c == '-':
                flag = -1
                continue
            if c == '+':
                continue
            num = ord(c) - ord('0')
            result = result*10 + num
            
        return result*flag

以上是初步代码,还有很多需要改善,逻辑关系没有划分很清楚,没有考虑到越界,递归调用看似简便但开销大,使用两个循环,略显臃肿。

class Solution(object):
    def myAtoi(self, str):
        """
        :type str: str
        :rtype: int
        """
        result, i, flag = 0, 0, 1
        if len(str) == 0:
            return 0
        while str[i] == ' ':
            i += 1
        if str[i] == '-':
            flag = -1
            i += 1
        elif str[i] == '+':
            i += 1
        
        while i<len(str) and str[i] >= '0' and str[i] <= '9':
            result = result*10 + ord(str[i]) - ord('0')
            i += 1
            if result > 2147483647:
                break
        
        result *= flag
        if result >= 2147483647:
            return 2147483647
        if result <= -2147483648:
            return -2147483648
        
        return result
        
if __name__ == '__main__':
    solution = Solution()
    print solution.myAtoi('1')

9. Palindrome Number

Determine whether an integer is a palindrome. Do this without extra space.

class Solution(object):
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        if x < 0:
            return False
            
        l = len(str(x)) - 1
        while l > 0:
            if x % 10 != x // 10**l:
                return False
            x = x // 10
            l -= 1
            x = x % 10**l
            l -= 1
            
        return True
        
if __name__ == '__main__':
    solution = Solution()
    print solution.isPalindrome(12313214)

算比较简单,第一次提交 81% ,第二次就 69% 第三次 21% 。也是很惶恐,本来开开心心。
赶紧找来别人的看看

class Solution:
    # @return a boolean
    def isPalindrome(self, x):
        if x < 0:
            return False
        copy, reverse = x, 0
        
        while copy:
            reverse *= 10
            reverse += copy % 10
            copy /= 10
        
        return x == reverse

if __name__ == "__main__":
    print Solution().isPalindrome(12321)
    print Solution().isPalindrome(12320)
    print Solution().isPalindrome(-12321)

這个看起来更优化点,一测试 30%,已经不知道说啥。

10. Regular Expression Matching

Implement regular expression matching with support for '.' and '*'.
'.' Matches any single character.
'*' Matches zero or more of the preceding element.

http://www.cnblogs.com/zuoyuan/p/3781773.html
最后一个‘*’一定不要下意识认为是正则表达式中匹配0或任意个字符,這里是匹配前面出现的字符,可以是不匹配(及匹配0次也可以重复)

class Solution:
    # @return a boolean
    def isMatch(self, s, p):
        if len(p)==0: return len(s)==0
        if len(p)==1 or p[1]!='*':
            if len(s)==0 or (s[0]!=p[0] and p[0]!='.'):
                return False
            return self.isMatch(s[1:],p[1:])
   
        else:
            i=-1; length=len(s)
            while i<length and (i<0 or p[0]=='.' or p[0]==s[i]):
                if self.isMatch(s[i+1:],p[2:]): return True
                i+=1
            return False

算法题理清思路很重要:

isMatch(s, p):

1. 当前p为0时,若s也是0时,则返回true,否则为false
2. 当前p不为0时,
  1) p的下一个不是'*'时
    if: 当前s与p匹配,
      则表明到此都是匹配的,只需要检查isMatch(s + 1, p + 1)
    else:
      返回false
  2) p的下一个是'*'时,
    while: 当前s与p匹配,即表明至此也是匹配的
      if: 当前s与下一个p也都匹配,即isMatch(s, p + 2),则返回true
      else: s++
    此时,当前s与当前p已经不匹配了(之前s都是匹配的),则检测下一个模板isMatch(s, p + 2)

上面是用递归方法,也有人说用动态规划比较好,待思考。http://www.cnblogs.com/flowerkzj/p/3726667.html

11、Container With Most Water

给定n个数,a1,a2,...,an.在坐标上的位置为(i,ai),求其中两个点到X轴的线段与x轴围成的面积最大。

思路:
1、暴力法:用两个for循环,超时了,看来还是得动脑子。
2、贪心法,从两边向中间夹逼,两个指针指向列表两端,当左边高度<右边时,制约在左边,右边往左移肯定找不到更大的,应该左边往右移,反之也成立。
但注意到,每次都会比较一次,但是当右移或左移的数比原来小时,没有必要进行计算,因为肯定会比原来结果小,如何优化代码。

class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        length = len(height) 
        if length < 2:
            return -1
        
        left = 0
        right = length - 1
        max_contain = 0
        while left < right:
            max_contain = max(max_contain, min(height[left] , height[right]) * (right - left))
            if height[left] < height[right]:
                left += 1
            else:
                right -= 1                                     
        return max_contain
                    
            
if __name__ == '__main__':
    solution = Solution()
    print solution.maxArea([1,3,56,57,8])

优化后,击败92%,欣慰。

class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        length = len(height) 
        if length < 2:
            return -1
        
        left = 0
        right = length - 1
        max_contain = 0
        while left < right:
            max_contain = max(max_contain, min(height[left] , height[right]) * (right - left))
            if height[left] < height[right]:
                j = left
                left += 1
                
                while height[left] <= height[j] and left < right: #若<原来的数,直接下一个,算都不用算
                    left += 1
            else:
                j = right
                right -= 1
                
                while height[right] <= height[j] and left < right:
                    right -= 1                                       
        return max_contain                               
if __name__ == '__main__':
    solution = Solution()
    print solution.maxArea([1,2])
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容

  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 9,287评论 0 23
  • NSArray内存布局 顺序存储结构与链式存储结构的比较(也可以说的顺序表与链表的比较
    iOS_愛OS阅读 243评论 0 0
  • Ⅰ、概念的到来主要源于感受,其次源于词汇积累。一个概念可以解释另外一个概念,概念之间可以相互关联,但却永远无法用概...
    奶香味旅途阅读 477评论 0 3
  • 江心映着明月 有了天涯与共的一瞬 秋水映着长天 有了鱼鸟齐飞的一刻 瞳孔映着谁 方有相濡以沫的一生 ——沧蓝
    一毫米阅读 263评论 0 2