LeetCode Daily Document

Document Policy

To keep practicing and try not to be left behind, I will continue to update my working through Problems on LeetCode. I will provide my solutions, which usually seems naive, and the Python3 version solution which gives me innavative insights about coding or from algorithm perspective.

打算在这里记录我的LeetCode佛系刷题生涯,我会在这里贴我自己的解答(python3)以及同语言解答中我认为比较推荐的答案。我本人的代码能力实在是不怎么样,会写出不忍直视的憨批算法,但是无所谓了,我感觉没人会看的,哈哈哈哈哈哈。这篇博客的主要以纪录为主,方便我以后回顾。以上。

Two Sum [Easy]

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.

输入一个list和一个目标和数值target,要求输出list中和(sum)为目标数值的index.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

My Solution:

Basically, my approach belongs to Brute Force with Time complexity $O(n^2)$ and Space complexity $O(1)$. The instance test runtime is 4932 ms and memory usage is 13.7 MB.

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        for i, n in enumerate(nums):
            for j in range(i+1,len(nums)):
                if n + nums[j] == target:
                    return([i, j])

Recomended Solution:

By utilizing Dictionary, this solution only walk through the whole list once to obtain the answer, which means Time complexity will be $O(n)$ with look up cost $O(1)$ and Space complexity is $O(n)$. The instance test runtime is 48 ms and memory usage is 14 MB.

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        h = {}
        for i, num in enumerate(nums):
            n = target - num
            if n not in h:
                h[num] = i
            else:
                return [h[n], i]

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.

My Solution:

The instance solution test runtime is 60 ms and memory usage is 12.8 MB.

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        accu = ListNode(0)
        t1 = l1
        t2 = l2
        c = 0
        t = t1.val + t2.val
        if t >= 10:
            accu.val = t % 10
            c += 1
        else:
            accu.val = t
        rn = accu
        t1 = t1.next
        t2 = t2.next
        while t1 != None or t2 != None:
            a = ListNode(0)
            if t1 == None:
                t1v = 0
            else:
                t1v = t1.val
                t1 = t1.next
            if t2 == None:
                t2v = 0
            else:
                t2v = t2.val
                t2 = t2.next
            if c == 1:
                t = t1v + t2v + 1
                c = 0
            else:
                t = t1v + t2v
            if t >= 10:
                a.val = t % 10
                c += 1
            else:
                a.val = t
            rn.next = a
            rn = a

        if c != 0:
            rn.next = ListNode(1)
        return (accu)

Recomended Solution:

This solution is recursive with test runtime 68 ms and memory usage 12.7 MB.

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        _ = l1.val + l2.val
        digit, tenth = _ % 10, _ // 10
        answer = ListNode(digit)
        if any((l1.next, l2.next, tenth)):
            l1 = l1.next if l1.next else ListNode(0)
            l2 = l2.next if l2.next else ListNode(0)
            l1.val += tenth
            answer.next = self.addTwoNumbers(l1, l2)    
        return answer

Longest Substring Without Repeating Characters

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

输入一个string,要求输出str中最长的不重复sub str的长度。

Example:

Input: "abcabcbb"
Output: 3 
Explanation: The answer is "abc", with the length of 3. 

My Solution:

The instance solution test runtime is 88 ms and memory usage is 12.8 MB.

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        lstr = 0
        tmp = {}
        que = []
        for ind, c in enumerate(s):
            if tmp.get(c) == None:
                tmp[c] = ind
                que.append(c)
            else:
                while tmp.get(c) != None and len(que) != 0:
                    del tmp[que.pop(0)]
                tmp[c] = ind
                que.append(c)
            lstr = max(lstr, len(tmp.keys()))
        return(lstr)

Recomended Solution:

This solution tracked the start pointer and the end pointer of the longest sub string, with test runtime 52 ms and memory usage 12.7 MB.

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        
        if len(s) == 0:
            return 0
        map = {}
        max_length = start = 0
        
        for i in range(len(s)):
            if s[i] in map and start <= map[s[i]]:
                start = map[s[i]] + 1
                
            else:
                max_length = max(max_length, i - start + 1)
            map[s[i]] = i
        return(max_length)

Longest Palindromic Substring

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

输入一个string,要求输出str中最长回文结构,若有多个会问return第一个(扩展到return全部也大同小异)。

Example:

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

My Solution:

The instance solution test runtime is 3368 ms and memory usage is 12.7 MB.

class Solution:
    def longestPalindrome(self, s: str) -> str:
        dic = {}
        longest_palindromic = ""
        for ind, cha in enumerate(s):
            if dic.__contains__(cha):
                for cind in dic[cha]:
                    temp = s[cind:ind+1]
                    is_pali = True
                    if temp[::-1] != temp:
                        is_pali = False
                    if is_pali:
                        pali = temp
                    else:
                        pali = cha
                    if len(longest_palindromic) < len(pali):
                        longest_palindromic = pali
                dic[cha].append(ind)
            else:
                dic[cha] = [ind]
                pali = cha
                if len(longest_palindromic) < len(pali):
                        longest_palindromic = pali
        return(longest_palindromic)

Recomended Solution:

This approach uses Dynamic Programming, with test runtime 4908 ms and memory usage 21.5 MB.

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        
        if len(s) == 0:
            return 0
        map = {}
        max_length = start = 0
        
        for i in range(len(s)):
            if s[i] in map and start <= map[s[i]]:
                start = map[s[i]] + 1
                
            else:
                max_length = max(max_length, i - start + 1)
            map[s[i]] = i
        return(max_length)

Runtime 964 ms and memory usage 12.6 MB. How made winds :D.

优美简洁,又快又好的代码orz。

class Solution:
    def longestPalindrome(self, s: str) -> str:
        p = ''
        for i in range(len(s)):
            p1 = self.get_palindrome(s, i, i+1)
            p2 = self.get_palindrome(s, i, i)
            p = max([p, p1, p2], key=lambda x: len(x))
        return p
    
    def get_palindrome(self, s: str, l: int, r: int) -> str:
        while l >= 0 and r < len(s) and s[l] == s[r]:
            l -= 1
            r += 1
        return s[l+1:r]

ZigZag Conversion

The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

输入字符串str以及行数numRows,将str的每个字符以z字形排列并以行顺序输出。

Example:

Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation:

P     I    N
A   L S  I G
Y A   H R
P     I

My Solution:

The instance solution test runtime is 52 ms and memory usage is 12.8 MB. Time complexity O(n)

其实重点就在于找到方向折返的判断条件。

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        output = ""
        rows = []
        for i in range(numRows):
            rows.append("")
        ind = 0
        indicator = 1
        for k in s:
            rows[ind] += k
            if numRows > 1:
                ind += indicator
            if ind == numRows or ind == -1:
                indicator = -indicator
                ind += 2*indicator
        for j in range(numRows):
            output += rows[j]
        return output

Recomended Solution:

这个算法思路和我的本质上是一致的,但是比我的优美,不需要判断numRows=1的这种情况。

def convert(self, s: str, numRows: int) -> str:
        if numRows == 1 or numRows >= len(s):
            return s
        
        row, step = 0, 0
        res = [''] * len(s)
        
        for c in s:
            res[row] += c
            
            if row == 0:
                step = 1
            elif row == numRows - 1:
                step = -1
                
            row += step
        
        return "".join(res)

Reverse Integer

Given a 32-bit signed integer, reverse digits of an integer.

Example:

Input: 123
Output: 321

Input: -123
Output: -321

Input: 120
Output: 21

My Solution:

The instance solution test runtime is 28 ms and memory usage is 12.7 MB.

其实基本想法就是每次余十除十,要特别注意的地方在于判断是否超过32-bit要在reverse之后判断。

class Solution:
    def reverse(self, x: int) -> int:
        neg = int(x) < 0
        out = 0
        if neg:
            indi = -1
            x = -x
        else:
            indi = 1
        while x >= 10:
            tail = x % 10
            out = out * 10 + tail
            x = (x - tail)/10
        out = int(indi * (out * 10 + x))
        if (out < -(2 ** 31)) or (out >= (2 ** 31)):
            out = 0
        return out

Recomended Solution:

附上别人的优美代码。我一辈子也想不起来用lambda

class Solution(object):
    
    def reverse(self, x):
        """
        :type x: int
        :rtype: int
        """
        
        order = lambda x: 0 if x == 0 else int(math.log(x, 10))
        sign = lambda x : 1 if (x > 0) else -1  
                                            
        num_sign = sign(x) 
        x = abs(x) 
        num_order = order(x)  
        answer = 0                                                    
        
        while num_order >= 0:
            last_num = x % 10 
            x = x // 10
            answer += last_num * 10 ** num_order
            num_order -= 1
            if not -2 ** 31 <= answer <= 2 ** 31 - 1:
                return 0
    
        return answer * num_sign