数据结构与算法 学习笔记(8):字典、集合、哈希表

本次文章记录的是和字典、集合、哈希表等数据结构相关的LeetCode算法题(题号与LeetCode对应),包括其构造和使用,针对每一题或一类题给出了相应的代码和思路分析,并有相应的注释。

题目1:1. Two Sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.

"""
分析:求两数和,并且nums里的元素只能使用一次,说明不能用两层循环来做(就算做了时间复杂度高O(n^2))
思路:
1.在遍历每一个元素的时候,记录下它和target之间的差,保存在字典中,并且记录下当前元素位置(要返回位置)
2.当后面的元素等于前面任意一个元素和target之差(即出现在dict中),那么dict中的元素和当前位置元素之和为target,此时返回dict中元素的值域(在nums中出现的位置)和当前位置i,作为列表返回
"""
class Solution:def twoSum(self, nums, target):""":type nums: List[int]:type target: int:rtype: List[int]"""#method 1if len(nums) <= 1:return [-1,-1]buff_dict = {}for i in range(len(nums)):if nums[i] in buff_dict:return [buff_dict[nums[i]], i]else:buff_dict[target - nums[i]] = i

题目2:136. Single Number

Given a non-empty array of integers, every element appears twice except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

"""
方法1:
字典保存下nums中每个字符出现的次数(作为value),遍历字典,返回value为1对应的key,需要字典的空间时间复杂度o(n),空间复杂度o(n)方法2:
If we take XOR of zero and some bit, it will return that bit
a⊕0=a
If we take XOR of two same bits, it will return 0
a⊕a=0
a⊕b⊕a=(a⊕a)⊕b=b
So we can XOR all bits together to find the unique number.时间复杂度o(n),空间复杂度o(1)
"""
class Solution(object):def singleNumber(self, nums):""":type nums: List[int]:rtype: int"""# method 1# mapping = {}# for i in range(len(nums)):#     if nums[i] not in mapping:#         mapping[nums[i]] = 1#     else:#         mapping[nums[i]] += 1# for key,value in mapping.items():#     if value == 1:#         return keyres = 0for num in nums:res ^= numreturn res

题目3:202. Happy Number

A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.

"""
思路:
在mem集合中保存计算过程中出现过的“平方和”,
如果某次计算的平方和出现在mem中,说明开始循环了,那么直接返回False
如果出现平方和为1,说明是happy number,返回True注:用集合来存储只出现一次的“平方和”是好方法
"""
class Solution(object):def isHappy(self, n):""":type n: int:rtype: bool"""if n <= 0:return Falsemem = set()while n != 1:n = sum([int(i) ** 2 for i in str(n)])if n in mem:return Falseelse:mem.add(n)else:return True

题目4:204. Count Primes

Count the number of prime numbers less than a non-negative number, n.

"""
思路:
prime列表把非素数对应的下标的值都置为0,素数的是1,求1的个数,就是求素数的个数
for 循环内部为 判断一个数是否为素数的方法。
"""
class Solution(object):def countPrimes(self, n):""":type n: int:rtype: int"""if n < 3:return 0primes = [1] * nprimes[0] = primes[1] = 0for i in range(2, int(n ** 0.5) + 1):if primes[i] == 1:primes[i*i: n: i] = [0] * len(primes[i*i: n: i])return sum(primes)

题目5:205. Isomorphic Strings

Given two strings s and t, determine if they are isomorphic.
Two strings are isomorphic if the characters in s can be replaced to get t.
All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself.

"""
方法1: 映射字符位置到d中方法2: 0.在array中保存 每个字符的前一次出现的位置(如果第一次出现,则保存当前位置)1.在字典中保存  每个字符的当前位置,以便下一次出现时可以读取出来,存到array中最后,如果sarray 和 tarray一样的,说明s和t的模式相同方法3:将方法2做一个整合,效果相同。三者的时间复杂度均为O(n),但方法1的空间复杂度更小一些"""
class Solution(object):def isIsomorphic(self, s, t):""":type s: str:type t: str:rtype: bool""""""method 1: a mapping """# d1, d2 = [0]*256, [0]*256# for i in range(len(s)):#     if d1[ord(s[i])] != d2[ord(t[i])]:#         return False#     d1[ord(s[i])] = i+1#     d2[ord(t[i])] = i+1# return True"""method 2: dict and array"""
#         n = len(s)
#         ss = {}
#         tt = {}
#         sarray = [0]*n
#         tarray = [0]*n
#         for i in range(n):
#             if s[i] not in ss:
#                 ss[s[i]] = i
#                 sarray[i] = i
#             else:
#                 sarray[i] =ss[s[i]]
#                 ss[s[i]] = i#         for j in range(n):
#             if t[j] not in tt:
#                 tt[t[j]] = j
#                 tarray[j] = j
#             else:
#                 tarray[j] =tt[t[j]]
#                 tt[t[j]] = j
#         return sarray == tarray """method 3: dict and array, improved verision of method 2"""n = len(s)ss = {}tt = {}sarray = [0]*ntarray = [0]*nfor i in range(n):if s[i] not in ss: # ss[s[i]] = isarray[i] = ielif s[i] in ss:sarray[i] =ss[s[i]]ss[s[i]] = iif t[i] not in tt:tt[t[i]] = itarray[i] = ielif t[i] in tt:tarray[i] =tt[t[i]]tt[t[i]] = ireturn sarray == tarray

题目6:217. Contains Duplicate

Given an array of integers, find if the array contains any duplicates.
Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.

"""
method 1:遍历列表nums,将字符保存在dic字典中,若再次出现,返回True.
method 2:将字典改为集合,可以不用存次数,减少部分空间开销.
method 3:return (len(nums) > len(set(nums))) 非常pythonic的做法
"""
class Solution(object):def containsDuplicate(self, nums):""":type nums: List[int]:rtype: bool"""# method 1:# n = len(nums)# if n == 0:#     return False# dic = {}# for i in range(n):#     if nums[i] in dic: #         return True#     else:#         dic[nums[i]] = 1# return False# method 2:# n = len(nums)# sett = set()# for i in range(n):#     if nums[i] in sett: #         return True#     else:#         sett.add(nums[i])# return False#method 3return len(nums) > len(set(nums))

题目7:219. Contains Duplicate II

Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k.

"""
与217 Contains Duplicate 相似,只需增加距离判断。
"""
class Solution(object):def containsNearbyDuplicate(self, nums, k):""":type nums: List[int]:type k: int:rtype: bool"""dic = {}for i in range(len(nums)):if nums[i] not in dic:dic[nums[i]] = ielse:dic[nums[i]] = i - dic[nums[i]]if dic[nums[i]] <= k:return Truereturn False

题目8:242. Valid Anagram

Given two strings s and t , write a function to determine if t is an anagram of s.

"""
方法1:只需存在s和t中字符出现次数的字典,比较两个字典是否相等即可。
time: O(n+m)
space: O(1) 因为字符的种类是有限的,不和n相关方法2:hashmap 构造一个hashmap存储26个字符出现的频次,存在对应的下标位置
如,a的次数存在dic[0],z的次数存在dic[25]
这样可以使得无需字典,只需一个数组,这样,比字典少存储键值。time: O(n+m)
space: O(1) """
class Solution(object):def isAnagram(self, s, t):""":type s: str:type t: str:rtype: bool"""# method 1# dic1 = {} # dic2 = {} # for i in range(len(s)):#     if s[i] in dic1:#         dic1[s[i]] += 1#     else:#         dic1[s[i]] = 1# for i in range(len(t)):#     if t[i] in dic2:#         dic2[t[i]] += 1#     else:#         dic2[t[i]] = 1# return dic1 == dic2dic1, dic2 = [0]*26, [0]*26for item in s:dic1[ord(item)-ord('a')] += 1 #ord返回item的ASCII码for item in t:dic2[ord(item)-ord('a')] += 1return dic1 == dic2

题目9:290. Word Pattern

Given a pattern and a string str, find if str follows the same pattern.
Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str.

"""
此题与205题相似,只不过这里需要先把str中的空格删除,并把每个单词分离,形成一个列表遍历。
"""
class Solution(object):def wordPattern(self, pattern, str):""":type pattern: str:type str: str:rtype: bool"""str = str.split(' ')dic1 = {}dic2 = {}array1 = [-1]*len(pattern)array2 = [-1]*len(str)for i in range(len(pattern)):if pattern[i] in dic1:array1[i] = dic1[pattern[i]]dic1[pattern[i]] = ielse:array1[i] = idic1[pattern[i]] = ifor i in range(len(str)):if str[i] in dic2:array2[i] = dic2[str[i]]dic2[str[i]] = ielse:array2[i] = idic2[str[i]] = ireturn array1 == array2

题目10:349. Intersection of Two Arrays

Given two arrays, write a function to compute their intersection.

"""
方法1: 从nums2中找在nums1中的数字,存入res.最后将res转换成list返回
方法2: 把nums1和nums2转成set,然后求交集,但本题就是要交集,用了&的话就不合适了。
"""
class Solution(object):def intersection(self, nums1, nums2):""":type nums1: List[int]:type nums2: List[int]:rtype: List[int]"""# method 1res = set()nums1 =set(nums1)for i in range(len(nums2)):if nums2[i] in nums1:res.add(nums2[i])return list(res)#method 2#return list(set(nums1) & set(nums2))

题目11:350. Intersection of Two Arrays II

Given two arrays, write a function to compute their intersection.

"""
方法1:nums2[i]出现在nums1中时,nums2[i]加入到res,然后删去nums1中的一个nums2[i].最后返回res方法2:   首先用一个字典counts存储nums1中数字出现的次数nums2[i]出现在nums1中时,nums2[i]加入到res,counts对应的值减1(若等于0,就不减了).
"""
class Solution(object):def intersect(self, nums1, nums2):""":type nums1: List[int]:type nums2: List[int]:rtype: List[int]"""# method 1 # res = []# for i in range(len(nums2)):#     if nums2[i] in nums1:#         res.append(nums2[i])#         nums1.remove(nums2[i])# return res# method 2counts = {}res = []for num in nums1:counts[num] = counts.get(num, 0) + 1for num in nums2:if num in counts and counts[num] > 0:res.append(num)counts[num] -= 1return res

题目12:387. First Unique Character in a String

Given a string, find the first non-repeating character in it and return it’s index. If it doesn’t exist, return -1.

"""
目标:找出未重复的元素+第一个未重复的 所以可分解为两步做
1.找出未重复的元素和其下标  遍历字符串用字典,字典存下每个字符的出现的位置,下标i;如果在后面的字符中又出现这个字符,则令其值为-1
2.第二步就是找出字典中不等于-1的且最小的数,这个数就是满足目标的数
3.如果字符串有不重复的数,则返回其下标;反之返回-1
"""
class Solution(object):def firstUniqChar(self, s):""":type s: str:rtype: int"""mapping = {}ans = len(s)temp = ansfor i, c in enumerate(s):if c in mapping:mapping[c] = -1else:mapping[c] = ifor c in mapping:if mapping[c] != -1:if mapping[c]<temp:temp = mapping[c]if temp!=ans:return temp else:return -1

题目13:389. Find the Difference

Given two strings s and t which consist of only lowercase letters.
String t is generated by random shuffling string s and then add one more letter at a random position.
Find the letter that was added in t.

"""
方法1:先统计s中的字符频次保存在dic中,t中的字符若在dic中,对应频次减1(直至0),若不在直接返回其。方法2: 参考LeetCode 136题(single number)0.s 和 t只相差一个字符,那么s + t 中,有一个单个的字符(其余都成对出现)。1.让其元素先与"0"异或,得到首字符,然后依次与后面的异或,根据异或的结合律等,最后的结果是单出来的那个字符。注:异或应在ASCII码域进行,完成后再转成字符形式返回
"""
class Solution(object):def findTheDifference(self, s, t):""":type s: str:type t: str:rtype: str"""# method 1: dict# dic = {}# for ch in s:#     dic[ch] = dic.get(ch,0) + 1# for c in t:#     if c in dic and dic[c] > 0:#         dic[c] -= 1#     else:#         return c# method 2: XORcode = 0for ch in s + t: code ^= ord(ch)return chr(code)

题目14:409. Longest Palindrome

Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters.
This is case sensitive, for example “Aa” is not considered a palindrome here.
Note:
Assume the length of given string will not exceed 1,010.

"""
分析:0. Sum代表能构成的回文最大长度,flag表示是否出现过频次为奇数的字符1. 首先是将s中的字符频次统计。2.遍历dic,如果当前字符频次为偶数,那么Sum和其频次相加;3.如果是奇数,Sum和其减1后的频次相加(奇数只有偶数部分的能构成回文)并设flag为1(因为单出来的可以放在回文中间)4.最后返回Sum +flag 就行时间复杂度 O(n)"""
class Solution(object):def longestPalindrome(self, s):""":type s: str:rtype: int"""Sum = 0flag = 0dic = {}for ch in s:dic[ch] = dic.get(ch,0) + 1for c in dic:if dic[c]%2 == 0:Sum += dic[c]else:flag = 1Sum += dic[c] -1return Sum + flag #flag代表统计的字符中有频次是奇数次的。

题目15:575. Distribute Candies

Given an integer array with even length, where different numbers in this array represent different kinds of candies. Each number means one candy of the corresponding kind. You need to distribute these candies equally in number to brother and sister. Return the maximum number of kinds of candies the sister could gain.

"""
0.sister尽可能多分,但要平均数量,所以最大为len(candies)//2;
1.sister想多分种类的话,必须得多拿单个的,最大就是每个种类拿一遍(set(candies))
3.取以上两个的小的那个,满足要求。
"""
class Solution(object):def distributeCandies(self, candies):""":type candies: List[int]:rtype: int"""#method 1 return min(len(candies) // 2, len(set(candies)))

题目16:594. Longest Harmonious Subsequence

We define a harmonious array is an array where the difference between its maximum value and its minimum value is exactly 1.
Now, given an integer array, you need to find the length of its longest harmonious subsequence among all its possible subsequences.

"""
要求:求值相差为1的最长序列
思路:如果我们把nums中每个数字出现的次数,保存在字典中那么把键值作为检索的标记,那么相邻的两个检索(键值差1的检索)的值域的和反应的是和谐序列,要求最长和谐序列,便是求最大的(相邻检索的值域的和)。注:求最大可以放在循环里保存更新,不需要全部求出后再求最大值,时间开销更少。
时间复杂度:构造字典O(n),求相邻键值和O(n),总共O(n)
"""
class Solution(object):def findLHS(self, nums):""":type nums: List[int]:rtype: int"""res=0mp={}for i in nums:if i not in mp:mp[i] = 1else:mp[i] += 1     for ch in mp:#mp.get(),返回指定键的值,如果键不存在,返回None# ch+1 保证不溢出,如果是ch,可能导致下一句中mp[ch+1]不存在,而出错if mp.get(ch+1,None): res=max(res,mp[ch] + mp[ch+1]) #相邻两个数字的次数和return res

题目17:1002. Find Common Characters

Given an array A of strings made only from lowercase letters, return a list of all characters that show up in all strings within the list (including duplicates). For example, if a character occurs 3 times in all strings but not 4 times, you need to include that character three times in the final answer.

"""
方法1:利用python内置容器Counter类(字典的子类)Counter(x)能返回x的每个元素出现的次数
此题思路:
0.由A[0]创建Conter对象res,统计A[0]中每个字符出现的次数
1.随后遍历A列表中的每个str,也用Counter对象去保存,然后与res求交集.
2.返回时将Counter对象res转换为列表。方法2和方法1思想是一样的,实现思路一样,但形式更加底层。
"""
class Solution(object):def commonChars(self, A):""":type A: List[str]:rtype: List[str]"""#         # method 1: pythonic
#         res = collections.Counter(A[0])
#         for a in A:
#             res &= collections.Counter(a)
#         return list(res.elements())# method 2: not build-in answer = Nonefor a in A:# create the counts for the current wordwork = {}for c in a:if c in work:work[c] += 1else:work[c] = 1# compare the current word counts# keep the least of the common ones# delete the ones in the answer not found in the current wordif answer != None:keys = list(answer.keys())for k in keys:if k in work:answer[k] = min(answer[k], work[k])else:del answer[k]else:answer = work# turn the counts into an arrayanswerArr = []for key in answer:count = answer[key]for _ in xrange(count):answerArr.append(key)return answerArr

本次记录就到这为止~

说明

本文章所有代码及文档均以上传至github中,感谢您的rp and star.

github链接:https://github.com/LSayhi
点击阅读原文:https://github.com/LSayhi/Algorithms

CSDN链接:https://blog.csdn.net/LSayhi

微信公众号:AI有点可ai

数据结构与算法 学习笔记(8):字典、集合、哈希表相关推荐

  1. 数据结构与算法学习笔记之 从0编号的数组

    数据结构与算法学习笔记之 从0编号的数组 前言 数组看似简单,但掌握精髓的却没有多少:他既是编程语言中的数据类型,又是最基础的数据结构: 一个小问题: 为什么数据要从0开始编号,而不是 从1开始呢? ...

  2. 数据结构与算法学习笔记15:最大流问题 / 二分图 / 有权无权二分图的匹配 / 匈牙利算法 / 银行家算法 / 稳定婚配

    数据结构与算法学习笔记15:最大流问题 / 二分图 / 有权无权二分图的匹配 / 匈牙利算法 / 银行家算法 / 稳定婚配 引入小题:最短路径 最大流问题(maximum flow problem) ...

  3. 数据结构与算法 学习笔记(5):字符串

    数据结构与算法 学习笔记(5)- 字符串 本次笔记记录了LeetCode中关于字符串的一些问题,并给出了相应的思路说明和代码.题目编号与LeetCode对应,方便查找. 题目1:LeetCode 13 ...

  4. 数据结构与算法学习笔记——图 C++实现

    数据结构与算法学习笔记--图 C++实现 1 概念 2 图的表示方法 3 算法 3.1 拓扑排序 3.2 图的搜索算法 3.2.1 广度优先搜索(BFS) 3.2.2 深度优先搜索(DFS) 3.3 ...

  5. 数据结构与算法学习笔记之 提高读取性能的链表(上)

    数据结构与算法学习笔记之 提高读取性能的链表(上) 前言 链表(Linked list)比数组稍微复杂一点,在我们生活中用到最常见的应该是缓存,它是一种提高数据读取性能的技术,常见的如cpu缓存,浏览 ...

  6. 数据结构与算法学习笔记——链栈

    数据结构与算法学习笔记(C语言) 链栈 在开始链栈的学习之前,我们先实现一下上一篇文章中提到的检查括号匹配的小程序,鉴于水平有限,本人就随便写一下代码好了,目标仅限于对功能的实现. /*用顺序栈这种数 ...

  7. 数据结构与算法学习笔记4:递归+分治法

    数据结构与算法学习笔记4 递归 斐波那契数列 青蛙跳台阶问题 链表倒序打印 分治法 二分查找/折半查找 Binary Search 题目1:快速幂 题目2:如何判断一个数是否为2的次幂 递归 指在函数 ...

  8. 数据结构与算法学习笔记之先进先出的队列

    前言 队列是一种非常实用的数据结构,类似于生活中发排队,可应用于生活,开发中各个方面,比如共享打印机(先请求先打印),消息队列.你想知道他们是怎么工作的么.那就来一起学习一下队列吧 正文 一.队列的定 ...

  9. 【数据结构与算法学习笔记】

    文章目录 前言 0 Preview与算法复杂度分析简述 1 线性数据结构 1.1 Stack 1.2 Queue 1.3 Deque 1.4 UnorderedList 1.5 OrderedList ...

最新文章

  1. Flex实现页面多态--state对象
  2. A Learned Representation for Artistic Style论文理解
  3. MATLAB应用实战系列NSGA-II多目标优化算法原理及应用实例(附MATLAB代码)
  4. Scala:提取器(Extractor)
  5. springcloud断路器修改熔断时间_SpringCloud(四)Hystrix服务降级,服务熔断
  6. 跑跑卡丁车rush服务器维护,跑跑卡丁车Rush+测试服
  7. SpringBoot(二)
  8. 15款用Unity开发iOS、安卓手机游戏的必备插件
  9. linux系统支持网银吗,Linux系统能使用网银吗?
  10. 100个开源游戏-街机类、棋牌类、休闲益智类、教育类、音乐类、RPG和AVG、策略类开源游戏【转】...
  11. matlab/simulink电力电子仿真斜坡信号Ramp设置和使用
  12. 怎么理解token,tokenize,tokenizer.
  13. LeCo-121. 买卖股票的最佳时机
  14. ubuntu进入终端界面输入密码错误login incorrect的解决办法
  15. “一帮一学习小组”是中小学中常见的学习组织方式,老师把学习成绩靠前的学生跟学习成绩靠后的学生排在一组。本题就请你编写程序帮助老师自动完成这个分配工作,即在得到全班学生的排名后,在当前尚未分组的学生中,
  16. 摩王软件OA+系统功能简介
  17. ABAP 创建Rest接口实例
  18. 《小岛经济学》二、一切经济都从何开始
  19. 【每日早报】2019/09/06
  20. DevOps实战系列【第八章】:详解Jenkins集成Docker私服Nexus3

热门文章

  1. 【MATLAB函数】function定义函数
  2. andorid中植入广告
  3. 直播预告:知识图谱推理问答综述 | AI TIME PhD 知识图谱专题-3
  4. unity脚本编辑器(一)
  5. 产品从0-1的流程及相关输出物内容说明
  6. python的matplotlib的常用绘图函数模版
  7. kendoui固定宽度_Kendoui之grid保存为Excel
  8. 《SQL必知必会阅读思维导图》PART3
  9. 基于Android的菜谱推荐系统,基于Android的健康食谱推荐系统研建
  10. 【数字图像处理】期末考试备考复习宝典 (一文搞定,期末考试不再担忧)