训练营day6-7:数组篇

目录

1、LeetCode :242.有效的字母异位词

2、349. 两个数组的交集

3、202. 快乐数

4、1. 两数之和

5、454. 四数相加 II

6、383. 赎金信

7、15. 三数之和

8、18. 四数之和


1、LeetCode :242.有效的字母异位词

还是比较简单的,直接统计就行

def isAnagram242(s, t):
    ss={}
    if len(s)!=len(t):
        return False
    for i in range(len(s)):
        if s[i] in ss:
            ss[s[i]] = ss[s[i]]+1
        else:
            ss[s[i]] = 1
    for j in range(len(t)):
        if t[j] in ss and ss[t[j]]>0:
            ss[t[j]] = ss[t[j]]-1
        else:
            return False

    return True

2、349. 两个数组的交集

def intersection349( nums1, nums2):
    nums1 = set(nums1)
    nums2 = set(nums2)
    res = []
    for i in nums1:
        if i in nums2:
            res.append(i)
    return res
def intersection34902( nums1, nums2):
    res = []
    for i in nums1:
        if i in nums2 and i not in res:
            res.append(i)
    return res

3、202. 快乐数

 终点是无线循环,会出现重复的数才退出循环

def isHappy202(n):
    sum=[]
    while(n!=1):
        s = 0
        for i in str(n):
            s = s+int(i)*int(i)
        n= s
        if n in sum:
            return False
        sum.append(n)

    return True

4、
1. 两数之和

 第一反应就是排序+双指针,但因为要返回下标,又进行了一次for

def twoSum1( nums, target):
    numsa = sorted(nums)
    i =0
    j = len(numsa)-1
    while(itarget:
            j=j-1
        else:
            i = i+1
    i1 = numsa[i]
    j1 = numsa[j]
    s1 = -1
    s2 = -1
    for k in range(len(nums)):
        if nums[k]==i1 and s1==-1 :
            s1 = k
        elif nums[k]==j1:
            s2 = k

    return [s1,s2]

 题解应该是用map,感觉思路差不多,,而已find in 不就又是一次for吗,但时间从52到了48,两层for循环达到了1531ms,看来还是不一样

def twoSum102( nums, target):
    map = {}
    for i in range(len(nums)):
        map[nums[i]] = i
    for i in range(len(nums)):
        tmp = target - nums[i]
        if tmp in map and map[tmp] != i:
            return [i, map[tmp]]

5、
454. 四数相加 II

 跟前面有点类似,第一想法就是两两相加,但我写的计算出来怎么怎么慢608ms,题解也很慢548ms,好吧,看来还是c++快吧

def fourSumCount454(nums1, nums2, nums3, nums4):
    map1 ={}
    for i in range(len(nums1)):
        for j in range(len(nums2)):
            s = nums1[i]+nums2[j]
            if s in map:
                map1[s] = map1[s]+1
            else:
                map1[s] =1
    map2 ={}
    c = 0
    for i in range(len(nums3)):
        for j in range(len(nums4)):
            s = nums3[i]+nums4[j]
            if -1*s in map1:
                c = c+map1[-1*s]
    return c

6、
383. 赎金信

 这种题思路就比较一致,匹配的就直接map查找就行,C++的话数组可能会更快一点

def canConstruct383( ransomNote, magazine):
    map={}
    for i in magazine:
        if i in map:
            map[i] = map[i]+1
        else:
            map[i]=1
    for i in ransomNote:
        if i in map and map[i]>0:
            map[i] = map[i]-1
        else:
            return False
    return True

7、
15. 三数之和

def threeSum15(nums):
    nums = sorted(nums)
    res = []
    for i in range(len(nums)):
        if nums[i]>0:
            break
        tmp = -1*nums[i]
        l = i+1
        r = len(nums)-1
        while(ltmp:
                r = r-1
            else:
                l = l+1
    return res

理论上不需要说啥但是也太慢了,6004ms,一个去重,降到4696ms

            if i>0 and nums[i]==nums[i-1]:
                continue

 把res里面的去重拿到外面,降到1248ms,只打败了41%的python3用户,剩下的人是怎么做到的

def threeSum1502( nums):
    nums = sorted(nums)
    res = []
    for i in range(len(nums)):
        if nums[i] > 0:
            break
        if i > 0 and nums[i] == nums[i - 1]:
            continue
        tmp = -1 * nums[i]
        l = i + 1
        r = len(nums) - 1
        while (l < r):
            if nums[l] + nums[r] == tmp:
                res.append([nums[i], nums[l], nums[r]])
            if nums[l] + nums[r] > tmp:
                r = r - 1
                while (l < r and nums[r] == nums[r + 1]):
                    r = r - 1
            else:
                l = l + 1
                while (l < r and nums[l] == nums[l - 1]):
                    l = l + 1
    return res

8、
18. 四数之和

四数之和,跟前面三数之和类似,主要是剪枝,和有可能是负数,不能直接比大小,直接上最后的剪完版本772ms

 def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        nums = sorted(nums)
        all=[]
        for i in range(len(nums)-3):
            if nums[i]>target and nums[i]>0:
                break
            if i>0 and nums[i]==nums[i-1]:
                continue
            for j in range(i+1,len(nums)):
                sum = nums[i]+nums[j]
                if sum>target and nums[j]>0:
                    break
                if j>i+1 and nums[j]==nums[j-1]:
                    continue
                l=j+1
                r = len(nums)-1
                while(ltarget-sum:
                        r = r-1
                        while (l < r and nums[r] == nums[r + 1]):
                            r = r - 1
                    else:
                        l=l+1
                        while (l < r and nums[l] == nums[l - 1]):
                            l = l + 1
        return all

总结:

数组主要是逻辑的东西,好像之前也又做过,还是快的

查找匹配直接上map(python只验证了逻辑,c++应该要考虑结构,数组,集合,映射之类的)

数组很多是双指针

你可能感兴趣的:(代码随想录训练营,leetcode,数组,python)