Leetcode刷题第七周--基本数据结构

Leetcode 1. 两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

解题思路:一种是遍历一遍,复杂度O(n2),也可以使用额外的字典来存储,只需要O(n)的复杂度。

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        dic = {}
        for i in range(len(nums)):
            another = target - nums[i]
            if another in dic.keys():
                res = (dic[another], i)
            else:  
                dic[nums[i]] = i
        return res

Leetcode 187. 重复的DNA序列

所有 DNA 由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:“ACGAATTCCG”。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。编写一个函数来查找 DNA 分子中所有出现超多一次的10个字母长的序列(子串)。
示例:
输入: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
输出: ["AAAAACCCCC", "CCCCCAAAAA"]

解题思路:用字典存储所有长度大于10的序列及其个数,然后输出个数大于2的序列。

class Solution(object):
    def findRepeatedDnaSequences(self, s):
        """
        :type s: str
        :rtype: List[str]
        """
        dic = {}
        res = []
        
        if len(s) < 10:
            return None
        
        for i in range(len(s)-10 + 1):
            key = s[i:i+10]
            if key not in dic:
                dic[key] = 1
            else:
                dic[key] += 1
        for j in dic.keys():
            if dic[j] > 1:
                res.append(j)
        return res

Leetcode 652. 寻找重复结点

给定一棵二叉树,返回所有重复的子树。对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可。两棵树重复是指它们具有相同的结构以及相同的结点值。

图片.png

解题思路:前序遍历这棵树,然后把所有节点的前序遍历结果存在字典里面,然后看会不会重复。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def dfs(self, root, hashmap, ans):
        if root == None:
            return '#END#'
        my_order = str(root.val) + '\t' + self.dfs(root.left, hashmap, ans) + '\t' + self.dfs(root.right, hashmap, ans) 
        if hashmap.get(my_order) == 1:
            ans.append(root)
        hashmap[my_order] = max(1, hashmap.get(my_order, 0) + 1)
        return my_order
        
    def findDuplicateSubtrees(self, root):
        """
        :type root: TreeNode
        :rtype: List[TreeNode]
        """
        hashmap = {}
        ans = []
        self.dfs(root, hashmap, ans)
        return ans

Leetcode 560. 和为K的子数组

给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。
示例 1 :输入:nums = [1,1,1], k = 2
输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。
说明 :
数组的长度为 [1, 20,000]。
数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。

解题思路:
前缀和
P[i] = A[0] + A[1] + … + A[i-1]
P[j] = A[0] + A[1] + … + A[j-1]
那么P[j] – P[i] = A[i] + A[i+1] + … + A[j-1]。
如果P[j] – P[i] == S的话,那么[i,j]就是符合条件的区间。所以对于每个j,只要计算有多少个i使得P[j] – P[i] == S。

class Solution(object):
    def subarraySum(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        hashmap = {0:1}
        cur_sum = 0
        res = 0
        
        for num in nums:
            cur_sum += num
            if cur_sum - k in hashmap:
                res += hashmap[cur_sum-k]
            hashmap[cur_sum] = hashmap[cur_sum] + 1 if cur_sum in hashmap else 1
        return res

Leetcode 547. 朋友圈

班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。
给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果M[i][j] = 1,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。
示例 1:
输入:
[[1,1,0],
[1,1,0],
[0,0,1]]
输出: 2
说明:已知学生0和学生1互为朋友,他们在一个朋友圈。
第2个学生自己在一个朋友圈。所以返回2。
示例 2:
输入:
[[1,1,0],
[1,1,1],
[0,1,1]]
输出: 1
说明:已知学生0和学生1互为朋友,学生1和学生2互为朋友,所以学生0和学生2也是朋友,所以他们三个在一个朋友圈,返回1。

解题思路:查并集,首先将每个元素初始化与自己的下标相对应,然后根据然后根据合并后下标的个数决定最终划分的集合个数。


图片.png
class Solution(object):
    def find(self, i, f):
        if i == f[i]:
            return i
        else:
            return self.find(f[i], f)
        
    def findCircleNum(self, M):
        """
        :type M: List[List[int]]
        :rtype: int
        """
        n = len(M)
        f = [i for i in range(n)]
        for i in range(n):
            for j in range(i+1, n):
                if M[i][j] == 1:
                    dx = self.find(i, f)
                    dy = self.find(j, f)
                    if dx != dy:
                        f[dy] = dx
        ans = 0
        for i in range(n):
            if i == self.find(i, f):
                ans += 1
        return ans

Leetcode 684. 冗余连接

图片.png

解题思路:跟上一题一样,采用查并集法,每次往树结构里面增加一条边,如果增加的边上面的点以前出现过的话,那么就具有了连通性,从而判断是否为冗余边。

class Solution(object):
    def find(self, i, f):
        if i == f[i]:
            return i
        else:
            return self.find(f[i], f)
        
    def findRedundantConnection(self, edges):
        """
        :type edges: List[List[int]]
        :rtype: List[int]
        """
        n = len(edges)
        f = list(range(n+1))
        for e in edges:
            p1 = self.find(e[0], f)
            p2 = self.find(e[1], f)
            if p1 == p2:
                return e
            f[p2] = p1

Leetcode 692. 前K个高频单词

图片.png

解题思路:这里用到了优先队列。先统计所有词的词频存起来,然后取字典里面的前K个,放进初始的优先队列,然后比较后面的词频与优先队列中最小的词频的大小,如果词频更大,则进入优先队列。最后将优先队列中的词逆序输出。

import queue

class word:
    def __init__(self, str, count):
        self.str = str
        self.count = count

    def __gt__(self, other):
        if self.count == other.count:
            return self.str < other.str
        else:
            return self.count > other.count

    def __lt__(self, other):
        if self.count == other.count:
            return self.str > other.str
        else:
            return self.count < other.count

class Solution(object):
    def topKFrequent(self, words, k):
        hash = {}
        for w in words:
            if w not in hash.keys():
                hash[w] = 1
            else:
                hash[w] += 1

        dict = [word(w, hash[w]) for w in hash.keys()]
        que = queue.PriorityQueue()
        for i in range(k):
            que.put(dict[i])
        for i in range(k, len(dict)):
            if dict[i] > que.queue[0]:
                que.get()
                que.put(dict[i])

        res = []
        while not que.empty():
            res.append(que.get().str)
        res = res[::-1]
        return res

Leetcode 295. 数据流的中位数

中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。
例如,
[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:
void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。

class Solution:
    def minWindow(self, s: 'str', t: 'str') -> 'str':
        from collections import defaultdict
        lookup = defaultdict(int)
        for c in t:
            lookup[c] += 1

        start = 0
        end = 0
        min_len = float("inf")
        counter = len(t)
        res = ""
        while end < len(s):
            if lookup[s[end]] > 0:
                counter -= 1
            lookup[s[end]] -= 1
            end += 1
            while counter == 0:
                if min_len > end - start:
                    min_len = end - start
                    res = s[start:end]
                if lookup[s[start]] == 0:
                    counter += 1
                lookup[s[start]] += 1
                start += 1
        return res
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容