leetcode practice - python3 (1)

48 篇文章 0 订阅
15 篇文章 0 订阅

1. Two Sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

最简单的想法, 遍历所有的数,两两组合,满足条件就返回:

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """

        ret = []
        for i in range(len(nums)):
            for j in range(len(nums)):
                if (i != j) and nums[i] + nums[j] == target:
                    return [i, j]

结果:超时

改进:用字典保存已扫描过的数及其下标,扫到一个数x时,字典中查找target - x是否在字典中,若在则找到结果。

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        d = {}
        length = len(nums)
        for i in range(length):
            if target - nums[i] in d:
                j = d.get(target - nums[i])
                if j != i:
                    return [i, j]
            d[nums[i]] = i


solution = Solution()
nums = [3, 2, 4]
target = 6
ans = solution.twoSum(nums, target)
print(ans)

结果:Beat 97.41% python3 at 2018-4-21

2. Add Two Numbers

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.

Example
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.

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

class Solution:
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """

        if l1 is None or l2 is None:
            return None

        ans = None
        tail = None
        while l1 is not None or l2 is not None:
            node = ListNode(0)
            if l1 is not None:
                node.val += l1.val
                l1 = l1.next
            if l2 is not None:
                node.val += l2.val
                l2 = l2.next

            if ans is None:
                ans = node
            else:
                tail.next = node
            tail = node

        tail = ans
        carry = False
        while True:
            if carry:
                tail.val += 1
                carry = False
            if tail.val >= 10:
                tail.val -= 10
                carry = True

            if tail.next is None:
                break

            tail = tail.next

        if carry:
            node = ListNode(1)
            tail.next = node

        return ans

简单的想法:
一一对应地将两个链表加起来,如果一个链已经到结尾则只加另一个。
扫描一遍结果的链表,有进位则处理进位。
结果 Beat 94.01% python3 at 2018-04-22

优化:复用链表的节点

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

class Solution:
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """

        if l1 is None or l2 is None:
            return None

        p1, p2 = l1, l2
        t1, t1 = l1, l2
        carry = 0
        while p1 != None and p2 != None:
            p1.val += p2.val + carry
            carry = p1.val // 10
            p1.val %= 10
            p2.val = p1.val

            t1, t2 = p1, p2
            p1, p2 = p1.next, p2.next

        ans, tail, p = l1, t1, p1
        if p2 != None:
            ans, tail, p = l2, t2, p2

        while p != None:
            p.val += carry
            carry = p.val // 10
            p.val %= 10
            tail = p
            p = p.next


        if carry:
            tail.next = ListNode(carry)

        return ans

结果 Beat 99.68% python3 at 2018-05-02

3. Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters.

Examples:
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.

没有重复字符的子串,简单的想法,用一个256大小的数组表示256个字符是否已出现过,初始化为全0,begin, end维护一个不含重复字符的子串的范围,end一直往后找,直到找到一个已在这个序列中的字符为止,找到后begin 向前移动,直到找到跟end相同的字符,保持[begin, end) 不含相同字符。

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        length = len(s)
        if length == 0:
            return 0

        begin = 0
        end = begin + 1
        ans = 1

        m = [ 0 for i in range(256) ]
        m[ord(s[begin])] = 1

        while end < length:
            if m[ord(s[end])] != 0:
                while begin <= end:
                    m[ord(s[begin])] = 0
                    begin += 1
                    if s[begin-1] == s[end]:
                        break

            m[ord(s[end])] = 1
            end += 1
            ans = max(ans, end - begin)

        return ans

Beat 50.04% python3 at 2018-04-23

优化:当找到一个已存在的字符时,begin有个一直前移,找到跟end相同字符的动作,用m之间记录这个位置,可省略这个往前移动的动作:

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        length = len(s)
        if length == 0:
            return 0

        begin = -1
        ans = 0
        m = [ 0 for i in range(256) ]

        for end, c in enumerate(s):
            begin = max(begin, m[ord(c)])
            m[ord(c)] = end + 1

            ans = max(ans, end - begin + 1)

        return ans

Beat 63.11% python3 at 2018-04-23

还是不太理想,将m 从list换成dict:

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        begin = -1
        ans = 0
        dict = {}

        for end, c in enumerate(s):
            if c in dict and dict[c] > begin:
                begin = dict[c]
            else:
                ans = max(ans, end-begin)
            dict[c] = end

        return ans

Beat 99.20% python3 at 2018-04-23

647. Palindromic Substrings

Given a string, your task is to count how many palindromic substrings in this string.
The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters.

Example 1:
Input: “abc”
Output: 3
Explanation: Three palindromic strings: “a”, “b”, “c”.
Example 2:
Input: “aaa”
Output: 6
Explanation: Six palindromic strings: “a”, “a”, “a”, “aa”, “aa”, “aaa”.
Note:
The input string length won’t exceed 1000.

方法:让每一个字母当中点,有两类回文方式:
1) axa
2) axxa

class Solution:
    def countSubstrings(self, s):
        """
        :type s: str
        :rtype: int
        """
        ans = 0
        length = len(s)
        for i in range(length):
            j = 0
            while i - j >= 0 and i + j < length and s[i-j] == s[i+j]:
                j += 1
                ans += 1

            j = 0
            while i - j >= 0 and i + j + 1 < length and s[i-j] == s[i+j+1]:
                j += 1
                ans += 1

        return ans

Beat 71.9% python3 at 2018-04-24

优化:数一下连续的相同字母,如连续3个a:aaa
回文串数a, a, a, aa, aa, aaa,个数3 + 2 + 1 = n*(n+1) / 2
然后从两个边界开始往两边数,比如baab,数到中间a时,连续两个a
aa往两边扩展都是b,得到baab,+1

class Solution:
    def countSubstrings(self, s):
        """
        :type s: str
        :rtype: int
        """
        ans = 0
        length = len(s)

        i = 0
        while i < length:
            j = i
            while j < length and s[j] == s[i]:
                j += 1
            ans += (j - i) * (j - i + 1) // 2

            l, r = i - 1, j
            while l >= 0 and r < length and s[l] == s[r]:
                l -= 1
                r += 1
                ans += 1

            i = j

        return ans

Beat 100.0% python3 at 2018-04-24

20. Valid Parentheses

Given a string containing just the characters ‘(‘, ‘)’, ‘{‘, ‘}’, ‘[’ and ‘]’, determine if the input string is valid.
An input string is valid if:
Open brackets must be closed by the same type of brackets.
Open brackets must be closed in the correct order.
Note that an empty string is also considered valid.

Example 1:
Input: “()”
Output: true

Example 2:
Input: “()[]{}”
Output: true

Example 3:
Input: “(]”
Output: false

Example 4:
Input: “([)]”
Output: false

Example 5:
Input: “{[]}”
Output: true

方法:使用栈碰到左半边就入栈,碰到右半边则与栈顶匹配

class Solution:
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        if len(s) % 2 != 0:
            return False

        l = []
        for c in s:
            if c == '(' or c == '[' or c == '{':
                l.append(c)
            else:
                if len(l) == 0:
                    return False

                top = l[-1]
                if c == ')' and top != '(':
                    return False
                elif c == ']' and top != '[':
                    return False
                elif c == '}' and top != '{':
                    return False

                l.pop()

        return len(l) == 0

Beat 90.78% python3 at 2018-04-25

优化:使用双端队列代替list

from collections import deque

class Solution:
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        if len(s) % 2 != 0:
            return False

        deq = deque()
        for c in s:
            if c == '(' or c == '[' or c == '{':
                deq.append(c)
            else:
                if len(deq) == 0:
                    return False

                top = deq[-1]
                if c == ')' and top != '(':
                    return False
                elif c == ']' and top != '[':
                    return False
                elif c == '}' and top != '{':
                    return False

                deq.pop()

        return len(deq) == 0

Beat 99.85% python3 at 2018-04-25

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值