垃圾小白羊leetcode刷题记录1

垃圾小白羊leetcode刷题记录1_第1张图片
我的解法:

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

两层循环,时间复杂度O(n2)

大佬解法:

def twoSum(self, nums: List[int], target: int) -> List[int]:
    num_dict = {
     }
    for i, num in enumerate(nums):
        if num_dict.get(target - num) is not None:
            return [num_dict.get(target - num), i]
        num_dict[num] = i

利用hash表,以空间换时间,只需一层循环,时间复杂度O(n)。


垃圾小白羊leetcode刷题记录1_第2张图片

我的解法:

def reverse(self, x: int) -> int:
    a = []
    x_inversed = 0
    signx = 1

    if x < 0:
        signx = -1
        x = -x
    if x == 0:
        return 0

    while x != 0:
        a.append(x%10)
        x = x//10
    for i in range(len(a)):
        x_inversed += a[len(a)-i-1]*(10**i)

    if (x_inversed <= 2**31-1) & (x_inversed >= -2**31):
        return x_inversed * signx
    else:
        return 0

特别处理x为负和零的情况,通过整除的方式获得各位数字,倒转后组合为反转后的数字。两次循环,时间复杂度O(2n)。

大佬解法:

def reverse(self, x: int) -> int:
    x_inversed = 0
    signx = 1

    if x < 0:
        signx = -1
        x = -x

    while x != 0:
        x_inversed = x_inversed*10 + (x%10)
        x = x//10

    if (x_inversed <= 2**31-1) & (x_inversed >= -2**31):
        return x_inversed * signx
    else:
        return 0

思路一致,算法更加优化简练,不需单独处理x为0的特殊情况,仅需一次循环,时间复杂度O(n)。


垃圾小白羊leetcode刷题记录1_第3张图片

我的解法:

def isPalindrome(self, x: int) -> bool:
    if x < 0:
        return False
    inversed = 0
    x1 = x
    while x1 !=0:
        inversed = inversed*10 + (x1%10)
        x1 = x1//10
    return x == inversed

单独考虑x小于0的情况,与前一题思路相似。

大佬解法:

class Solution:
    def isPalindrome(self, x: int) -> bool:
        xlist = list(str(x))
        l, r = 0, len(xlist)-1
        while r > l:
            if xlist[l] != xlist[r]:
                return False
            l += 1
            r -= 1
        return True

将数字转为字符列表,采用首位双指针的方式比对。


垃圾小白羊leetcode刷题记录1_第4张图片

我的解法:

class Solution:
    def romanToInt(self, s: str) -> int:
        d = {
     'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
        n = 0
        for i in range(len(s)-1):
            if d[s[i]] < d[s[i+1]]:
                n -= d[s[i]]
            else:
                n += d[s[i]]
        n += d[s[-1]]
        return n

若某位对应数字大于后一位,则减去该位,否则加上该位。


垃圾小白羊leetcode刷题记录1_第5张图片

我的解法:

class Solution:
    def isValid(self, s: str) -> bool:
        b = {
     '(':')', '{':'}', '[':']'}
        stack = ['base']
        s_list = list(s)
        for i in range(len(s_list)):
            if s_list[i] in b.keys():
                stack.append(b[s_list[i]])
            else:
                if s_list[i] != stack.pop():
                    return False
        return len(stack) == 1

遍历括号集,若出现某种左括号则把对应右括号压入栈;若出现右括号,弹出栈内第一个值,若不一致直接输出False。栈内初始设置一元素’base’,用以处理括号集第一个元素为右括号情况。遍历结束后判断栈内是否只剩下’base’,若是返回True。
优化:开头添加判断括号集长度是否为奇数,若是直接返回False。


垃圾小白羊leetcode刷题记录1_第6张图片
我的解法:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        if l1 is None:
            return l2
        elif l2 is None:
            return l1
        else:
            l = ListNode()
            header = l
            while 1:
                if l1.val <= l2.val:
                    l.next = l1
                    l = l.next
                    l1 = l1.next
                else:
                    l.next = l2
                    l = l.next
                    l2 = l2.next
                if l1 is None:
                    l.next = l2
                    break
                if l2 is None:
                    l.next = l1
                    break
            return header.next

首先特殊考虑l1或l2一者为空的情况。创建新链表l,遍历比对l1和l2数值大小,若其中一个链表遍历完成,则将另一链表的剩余部分直接附在结尾,结束循环。

大佬解法:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        if not l1:
            return l2
        if not l2:
            return l1
        if l1.val <= l2.val:
            l1.next = self.mergeTwoLists(l1.next, l2)
            return l1
        else:
            l2.next = self.mergeTwoLists(l1, l2.next)
            return l2

递归算法,相当于每次递归添加首元素较小链表的首元素,剩下部分与另一链表一起继续递归。


垃圾小白羊leetcode刷题记录1_第7张图片

我的解法:

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        if not nums:
            return None
        j = 1
        origin = nums[0]
        for i in range(1, len(nums)):
            if nums[i] != origin:
                nums[j] = nums[i]
                origin = nums[i]
                j += 1
        return j

由于数组是排序的,记录当前的数字,遍历数组,若出现与当前不同的数字,则将表头相应位置赋值为该数字,当前数字更新,继续遍历。

大佬解法:

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        pre,cur=0,1
        while cur<len(nums):       
            if nums[pre]==nums[cur]:
                nums.pop(cur)
            else:
                pre,cur=pre+1,cur+1
        return len(nums)

用两个指针,指向第一个和第二个元素,如果他们相等,删除第二个元素。指针还指向原来的位置,继续比较。不等的话,两个指针位置都加一。遍历结束即可。


垃圾小白羊leetcode刷题记录1_第8张图片

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

与前一题思路类似,将目标值全部置换到列表尾部。时间复杂度为O(n),强于直接使用remove的方法(O(n)2)。


垃圾小白羊leetcode刷题记录1_第9张图片

我的解法:

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        ln = len(needle)
        lh = len(haystack)
        i = 0
        j = 0
        t = -1
        while i <= lh - ln:
            while j < ln:
                if haystack[i] != needle[j]:
                    if t < 0:
                        i += 1
                    else:
                        i = t
                        t = -1
                    j = 0
                    break
                else:
                    j += 1
                    i += 1
                    if i == lh: break
                    if ((haystack[i] == needle[0]) & (j > 0) & (t < 0)):
                        t = i
            if j == ln:
                return i - ln
        return -1

略微改进的暴力遍历,如果首字母一直匹配不对,则退化为暴力遍历。若前若干字符匹配正确,needle第j个字符匹配失败且hatstack匹配正确的前j个字符中未出现needle首字符,则直接跳过当前匹配所有字符,从i+1处开始继续匹配。若出现过needle首字符,则i变更为其出现的第一个位置t。

大佬解法

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        ln = len(needle)
        lh = len(haystack)
            
        def calshift(s):
            shift = {
     }
            for i in range(ln-1, -1, -1):
                if not shift.get(needle[i]):
                    shift[needle[i]] = ln - i
            return shift[s] if shift.get(s) else ln+1
        
        if (not haystack) & (not needle):
            return 0
        if not haystack:
            return -1

        i = 0
        while i <= lh - ln:
            if haystack[i:i+ln] != needle:
                if i == lh - ln:
                    return -1
                else:
                    i = i + calshift(haystack[i+ln])
            else:
                return i
        return -1

使用偏移表,根据匹配字段后一位字符判断指针偏移的位数,当字符重复性不强时,可以大大提高匹配效率。
垃圾小白羊leetcode刷题记录1_第10张图片


垃圾小白羊leetcode刷题记录1_第11张图片

我的解法:

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        n = len(nums)
        if target <= nums[0]:
            return 0
        elif target > nums[-1]:
            return n
        else:
            l = 0
            r = n-1
            while r-l > 1:
                i = (l+r)//2
                if target >= nums[i]:
                    l = i
                else:
                    r = i
            return l if target <= nums[l] else l+1

特殊处理添加到头尾情况后,采用二分法查找。

你可能感兴趣的:(小白羊不太会编程,leetcode,数据结构,python,算法)