Leetcode刷题笔记:[No.1——No.49]

No.1: Two Sum
思路:一个下标循环记录,先定当前记录的数据,然后寻找下一个与之匹配的数据。
查找时可用hashmap查找,python3中的index(value)方法就是查找在一个数组范围内的value所对应的下标,如nums[i+1:].index(second)

class Solution:
    def twoSum(self, nums, target):
        for i in range(len(nums)):
            second = target - nums[i]
            if second in nums[i+1:]:
                j = nums[i+1:].index(second) + i + 1
                return i,j

No.2:Add Two Numbers
思路:先把两个链表元素reverse转为整数,然后整数相加再变成链表。注意无论是链转int还是int转链都要reverse。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def addTwoNumbers(self, l1, l2):
        res1 = 0;res2 = 0;
        i1 = i2 = 0
        while l1 or l2:
            if l1:
                res1 = res1 + l1.val * (10 ** i1)
                i1 += 1
                l1 = l1.next
            if l2:
                res2 = res2 + l2.val * (10 ** i2)
                i2 += 1
                l2 = l2.next
        res = res1 + res2;out = []
        if res == 0:
            out = [0]
        while res:
            out.append(res % 10)
            res //= 10
        return out

No.3:Longest Substring Without Repeating Characters
思路:Sliding Windows(移窗法),声明一个buf数组记录已经记录的字符串,用ij控制开始和结束的下标。当一个字母在buf中没出现过,则记录并更新ans=max(ans,j-i+1),然后j++;如果出现,则删除s[i]这个数值然后i++。最后return ans的值。

class Solution:
    def lengthOfLongestSubstring(self, s):
        ans = i = j = 0
        buf = []
        while i<len(s) and j<len(s):
            if s[j] not in buf:
                buf.append(s[j])
                ans = max(ans,j-i+1)
                j += 1
            else:
                buf.remove(s[i])
                i += 1
        return ans

No.7:Reverse Integer
思路:首先分情况,小于0的数标记后去绝对值,然后每次提取各位再加到结果的最前面,最后再对小于0的数添负号

class Solution:
    def reverse(self, x):
        res = 0
        flag = False
        if x < 0:
            flag = True
        x = abs(x)
        while x != 0:
            res = res * 10 + x % 10
            x = math.floor(x/10)
        if res>=math.pow(2,31):
            return 0
        else:
            if flag == True:
                res = -res
            return res

No.9:Palindrome Number
思路:判断一个数是否是回文数。

  • 首先,负数一定不是回文数,单独拉出来判断
  • 然后,对于非负数,先加个tmp用来保存x的初值,然后依据规则,根据x生成回文数,比较生成的回文数与原来的x是否相同,相同则返回true,否则返回false。
  • 注意,每次往前推tmp的时候要向下取整

    class Solution:
    def isPalindrome(self, x):
        if x < 0:
            return False
        tmp = x
        y = 0
        while tmp:
            y = y * 10 + tmp % 10
            tmp = math.floor(tmp/10)
        if x == y:
            return True
        else:
            return False

    No.13:Roman to Integer
    思路:题意为判断罗马数字的数值,规则为根据字母对应数值,而且小接大为减法,大接小为加法。所以先把字母转成数字,然后根据规则进行加减法运算即可

    class Solution:
    def romanToInt(self, s):
        sum = 0
        t = {"I":1,"V":5,"X":10,"L":50,"C":100,"D":500,"M":1000}
        ans = []
        for i in str(s):
            ans.append(t[i])
        print(ans)
        for i in range(len(s)-1):
            if ans[i] < ans[i+1]:
                sum = sum - ans[i]
            else:
                sum = sum + ans[i]
        sum = sum + ans[-1]
        return sum

    No.14:Longest Common Prefix
    思路:先假设第一个字符串最大,然后与后面的字符串比较取相同的最长前缀字符串,然后往后不断比较直至到最后找出最长的公共前缀字符串
    Alt text

    class Solution:
    def longestCommonPrefix(self, strs):
        if len(strs) == 0:
            return ""
        prefix = strs[0]
        for i in range(1,len(strs)):
            if not prefix: #prefix为空
                return ""
            else:
                while prefix not in strs[i][:len(prefix)] and len(prefix) > 0:
                    prefix = prefix[:len(prefix)-1]
        return prefix

    No.20:Valid Parentheses
    思路:括号匹配,将括号后与括号前分别做成key-value的map对应,遇到前部分符号,进栈。当找到后部分时,符号出栈,与对应的value比较,如果不符,则返回false,否则返回true

    class Solution:
    def isValid(self, s):
        pars = [None]
        parmap = {'}':'{',']':'[',')':'('}
        for c in s:
            if c in parmap:
                if parmap[c] != pars.pop():
                    return False
            else:
                pars.append(c)
        return len(pars) == 1

    No.21:Merge Two Sorted Lists
    思路:将两个排好序的链表重新按顺序Merge。
    首先,比较l1和l2在表头的值,将较小的那个链表next链接指向较大的链表头结点,这样就保证了总是较小数值的排在前面。最后观察哪个链表为空,就输出另外一个链表。
    Alt text

    #Definition for singly-linked list.
    #class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    class Solution:
    def mergeTwoLists(self, l1, l2):
        if l1 is None:
            return l2
        if l2 is None:
            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

    No.26:Remove Duplicates from Sorted Array
    思路1:[99ms],用两个指针进行循环比较,i为外循环、j为内循环,然后当nums[i]==nums[j]时,j++;不相等时,i向前推进,然后令nums[i]=nums[j]。最后返回i+1

    class Solution:
    def removeDuplicates(self, nums):
        if len(nums) == 0:
            return 0
        i = 0
        for j in range(1,len(nums)):
            if nums[j] != nums[i]:
                i += 1
                nums[i] = nums[j]
        return i + 1

    思路2:从后往前遍历数组,如发现相同的元素,就删除,最后返回数组的长度

    class Solution:
    def removeDuplicates(self, nums):
        if nums == []:
            return 0
        for i in range(len(nums)-1,0,-1):
            if nums[i] == nums[i-1]:
                del nums[i]
        return len(nums)

    No.27:Remove Element
    思路:在不开辟新数组的情况下,移除值为val的元素并返回新数组长度。
    利用双指针来做,i和j一快一慢,当nums[i]==val时,i++;不等于时,将后面非val的值赋值到前面,并更新j++。结束时,只需返回j即可。新数组就位于nums[:j],后面可以不访问而得到

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

    No.28:Implement strStr()
    思路1:直接利用python的index(str)函数,如果substring存在在string中,则返回substring的index值,否则返回-1

    class Solution:
    def strStr(self, haystack, needle):
        if needle in haystack:
            return haystack[:].index(needle)
        else:
            return -1

    思路2:循环遍历一次,每次查找string[i:i+len(substring)]是否等于substring,找到则返回i,否则返回-1

    class Solution:
    def strStr(self, haystack, needle):
        f = False
        for i in range(len(haystack) - len(needle) + 1):
            if haystack[i:i+len(needle)] == needle:
                return i
                f = True
        if f == False:
            return -1

    No.35:Search Insert Position
    思路1:循环遍历一遍数组,如果找到target,直接返回下标;如果最左边大于target,返回0;如果最右边小于target,返回len(nums)+1;如果在中间出现一个小于target一个大于target的数,返回中间的下标值

    class Solution:
    def searchInsert(self, nums, target):
        for i in range(len(nums)):
            if nums[i] == target:
                return i
            if i == len(nums) - 1 and nums[i] < target:
                return i + 1
            if i == 0 and nums[i] >target:
                return i
            if nums[i] < target and nums[i+1] > target:
                return i + 1

    思路2:由于是排序好的数组,故可用二分搜索,如果nums[i]>target,则往左边找,更新r的值;如果nums[i]<target,则往右边找,更新l的值。如果r - l <= 1,代表已锁定数组下标的位置,返回r。如果nums[i] == target,直接返回下标值

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

    No.743:(Contest)Network Delay Time
    思路:题意为给定一个有向有权重图,问从顶点K开始,经过多少时间能遍历全图。这题思路可以先将所有顶点置为INF,然后将K点置为0,接着从顶点出发查找邻点,如果找到且a[fr]+wei<a[to]时,代表是最短路径,更新a[to]的值,最后取a数组的最大值即可。如果发现有顶点值仍然为INF,代表没有被访问,输出-1。

    class Solution:
    def networkDelayTime(self, times, N, K):
        a = []
        for i in range(N+1):
            a.append(1e6)#代表没有被访问的顶点
        a[K] = 0
        for i in range(N):
            for j in range(len(times)):
                fr = times[j][0]
                to = times[j][1]
                wei = times[j][2]
                if a[fr] + wei < a[to]:
                    a[to] = a[fr] + wei
        ans = 0
        for i in range(1,N+1):
            if ans < a[i]:
                ans = a[i]
            if a[i] == 1e6:
                return -1
        return ans

    No.38:Count and Say
    思路:给定第一个字符串,构造后面的字符串,构造规则为
    全加(重复的次数+重复的数字)

    关于python的正则表达式:
    模块:import re
    re.findall(规则,目标字符串)
    r'(A)':忽略转义字符,以A规则查找
    \number:第number个重复的数字,
    (.):匹配任意字符串
    *:匹配任意个字符,紧跟在要匹配字符串后

    python实现代码:

    def countAndSay(self, n):
    s = '1'
    for _ in range(n - 1):
        s = ''.join(str(len(group)) + digit
                    for group, digit in re.findall(r'((.)\2*)', s))
    return s

猜你喜欢

转载自www.cnblogs.com/EchoWorld/p/9099517.html