算法题day6

一、复习链表题目:

1.leetcode题目 141环形链表(easy):

直接用快慢指针法,集合法很简单就不写了。

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

class Solution:
    def hasCycle(self, head: Optional[ListNode]) -> bool:
        if not head or not head.next:
            return False
        slow = head
        fast = head.next
        while fast and fast.next:
            if slow== fast:
                return True
            fast = fast.next.next
            slow = slow.next
        return False
        

2. leetcode题目 21.合并两个有序链表(easy):

题目描述:

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

解决:①迭代法:

# 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, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        cur1 = list1
        cur2 = list2
        cur3 = ListNode(0)
        cur = cur3
        while cur1 and cur2:
            if cur1.val <= cur2.val:
                cur.next = cur1
                cur1 = cur1.next
            else:
                cur.next = cur2
                cur2 = cur2.next
            cur = cur.next
        cur.next = cur1 if cur1 is not None else cur2
        return cur3.next

②递归法:

# 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, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        cur1 = list1
        cur2 = list2
        if not cur1:
            return cur2
        if not cur2:
            return cur1
        while cur1 and cur2:
            if cur1.val<=cur2.val:
                cur1.next = self.mergeTwoLists(cur1.next,cur2)
                return cur1
            else:
                cur2.next = self.mergeTwoLists(cur1,cur2.next)
                return cur2
        

二、哈希表:

1.leetcode题目 242 有效的字母异位词(easy)

题目描述:

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

解决:

①dictionary:

(我这个方法吧 跟官方题解还不太一样)

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        res = {}
        m = len(s)
        n = len(t)
        if m != n:
            return False
        for i in s:
            if i not in res:
                res[i] = 0
            res[i] += 1
        for j in t:
            if j not in res:
                return False
            else:
                res[j] -= 1
                if res[j] == 0:
                    del res[j]
        return True

②python中 直接计数:(内存和时间消耗比第一种方法大)

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        if Counter(s) == Counter(t):
            return True
        else:
            return False

③用defaultdict函数(方法一的简化版):

from collections import defaultdict
class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        s_d = defaultdict(int)
        t_d = defaultdict(int)
        for i in s:
            s_d[i] += 1
        for j in t:
            t_d[j] += 1
        return s_d== t_d

2.leetcode题目 赎金信(easy)

题目描述:

给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false 。

magazine 中的每个字符只能在 ransomNote 中使用一次。

解决:

①偷懒用defaltdict:

from collections import defaultdict
class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        r_dict = defaultdict(int)
        m_dict = defaultdict(int)
        if len(ransomNote) > len(magazine):
            return False
        else:
            for i in ransomNote:
                r_dict[i] += 1
            for j in magazine:
                m_dict[j] += 1
            if all(i in r_dict and m_dict[i]>=r_dict[i] for i in r_dict):
                return True
            else:
                return False

3.leetcode题目 49 字母异位词分组(medium):

题目描述:

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

个人思路(计数):

解决:


class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        dic = collections.defaultdict(list)
        s = []
        for string in strs:
            record = [0]*26
            for i in string:
                record[ord(i) - ord('a')] += 1
            record = tuple(record)
            dic[record].append(string)
        output = []
        for i in dic:
            output.append(dic[i])
        ##后面这个for循环可以替换成list(dic.values())
        return output

之前有过的思路:排序。 但是我当时不知道给字符串排序的函数(在这里不得不感叹一句collections.dafaultdict真牛):

解决:


class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        dic = collections.defaultdict(list)
        s = []
        for string in strs:
            i = "".join(sorted(string))
            dic[i].append(string)
        return list(dic.values())

4.leetcode题目 438找到字符串中所有字母异位词(medium):

思路:滑窗

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        record_p = [0]*26
        for i in p :
            record_p[ord(i) - ord('a')] += 1
        slow = 0
        fast = 0
        l = []
        n = len(s)
        record_s = [0]*26
        for fast in range(n):
            record_s[ord(s[fast]) -ord('a') ] += 1
            while record_s[ord(s[fast]) -ord('a') ]>record_p[ord(s[fast]) -ord('a') ]:
                record_s[ord(s[slow]) -ord('a')] -= 1
                slow += 1
            if record_s == record_p:
                l.append(slow)
        return l

5.leetcode题目 349.两个数组的交集(easy):

题目描述:给定两个数组 nums1 和 nums2 ,返回 它们的 交集。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

解决:

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        res = set()
        l = set()
        for i in nums1:
            res.add(i)
        for j in nums2:
            if j in res and j not in l:
                l.add(j)
        return list(l)

6.leetcode题目 350.两个数组的交集II(easy):

题目描述:给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。

解决:排序后双指针

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        nums1.sort()
        nums2.sort()
        index1 = 0
        index2 = 0
        l = list()
        while index1<len(nums1) and index2<len(nums2):
            if nums1[index1] < nums2[index2]:
                index1 += 1
            elif nums1[index1] > nums2[index2]:
                index2 += 1
            else:
                l.append(nums1[index1])
                index1 += 1
                index2 += 1
        return l

7.leetcode题目 202 快乐数(easy):

题目描述:

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

思路:(这题没啥思路,看了题解)

解决:

def isHappy(self, n: int) -> bool:  
    def get_next(number):
        total_sum = 0
        while number > 0:
            number, digit = divmod(number, 10)
            total_sum += digit ** 2
        return total_sum

    slow_runner = n
    fast_runner = get_next(n)
    while fast_runner != 1 and slow_runner != fast_runner:
        slow_runner = get_next(slow_runner)
        fast_runner = get_next(get_next(fast_runner))
    return fast_runner == 1

8.leetcode题目 1.两数之和(easy):

题目描述:

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

解决:

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        records = dict()
        for i,num in enumerate(nums):
            if target-num in records:
                return [records[target-num],i]
            records[nums[i]] = i
        return []

三、总结:

1.需要进脑子的知识:

①字母转数字用ord

②collections.defaultdict用法

③all()以及any()的用法

④字符串排序用sorted(string)

⑤明天重新看202 快乐数这道题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值