387. 字符串中的第一个唯一字符

思路

用map存储第一次出现时候的index,然后遍历map找到第一个只出现1次的字符

代码

  1. /**
  2. * @param {string} s
  3. * @return {number}
  4. */
  5. var firstUniqChar = function(s) {
  6. let obj = {};
  7. for(let i = 0; i < s.length; i ++) {
  8. let cur = s[i];
  9. if (!obj[cur]) {
  10. obj[cur] = {
  11. index: i,
  12. count: 1
  13. }
  14. } else {
  15. obj[cur].count += 1;
  16. }
  17. }
  18. for(let [key, {index, count}] of Object.entries(obj)) {
  19. if (count === 1) {
  20. return index
  21. }
  22. }
  23. return -1;
  24. };

复杂度分析

时间复杂度 字符的统计 - 图1#card=math&code=O%28N%29)
空间复杂度 字符的统计 - 图2#card=math&code=O%28N%29)

389. 找不同

思路

使用map将t中的char对应的count存起来,然后遍历s一个个减去 ,留下最后多出来的字符

代码

  1. /**
  2. * @param {string} s
  3. * @param {string} t
  4. * @return {character}
  5. */
  6. var findTheDifference = function(s, t) {
  7. let obj = {};
  8. for(let i = 0; i < t.length; i ++) {
  9. let cur = t[i]
  10. obj[cur] = (obj[cur] || 0) + 1
  11. }
  12. for(let i = 0; i < s.length; i ++) {
  13. let cur = s[i]
  14. obj[cur] = obj[cur] - 1
  15. if (obj[cur] === 0) {
  16. delete obj[cur]
  17. }
  18. }
  19. for(let key in obj) {
  20. return key
  21. }
  22. };

复杂度分析

时间复杂度 字符的统计 - 图3#card=math&code=O%28N%29)
空间复杂度 字符的统计 - 图4#card=math&code=O%28N%29)

383. 赎金信

思路

先用map将ransomNote中的char-count 存起来,然后遍历magazine减去,如果最后map空了,则可以包含

代码

  1. /**
  2. * @param {string} ransomNote
  3. * @param {string} magazine
  4. * @return {boolean}
  5. */
  6. var canConstruct = function(ransomNote, magazine) {
  7. let obj = {}
  8. for(let i = 0; i < ransomNote.length; i ++) {
  9. let cur =ransomNote[i];
  10. obj[cur] = (obj[cur] || 0) + 1
  11. }
  12. for(let i = 0; i < magazine.length; i ++) {
  13. let cur = magazine[i];
  14. if (obj[cur]) {
  15. obj[cur] = obj[cur] - 1;
  16. }
  17. if (obj[cur] === 0) {
  18. delete obj[cur]
  19. }
  20. }
  21. return Object.keys(obj).length === 0
  22. };

复杂度分析

时间复杂度 字符的统计 - 图5#card=math&code=O%28N%29)
空间复杂度 字符的统计 - 图6#card=math&code=O%28N%29)

242. 有效的字母异位词

思路

先用map存储key-count,然后再遍历t看能否使得map为空

代码

  1. /**
  2. * @param {string} s
  3. * @param {string} t
  4. * @return {boolean}
  5. */
  6. var isAnagram = function(s, t) {
  7. let obj = {}
  8. for(let i = 0; i < s.length; i ++) {
  9. let cur = s[i];
  10. obj[cur] = (obj[cur] || 0) + 1
  11. }
  12. for(let i = 0; i < t.length; i ++) {
  13. let cur = t[i];
  14. if (obj[cur] === undefined) return false;
  15. obj[cur] = obj[cur] - 1
  16. if (obj[cur] === 0) {
  17. delete obj[cur]
  18. }
  19. }
  20. return Object.keys(obj).length === 0
  21. };

复杂度分析

时间复杂度 字符的统计 - 图7#card=math&code=O%28N%29)
空间复杂度 字符的统计 - 图8#card=math&code=O%28N%29)

49. 字母异位词分组

思路

异位词排序后是相等的;
另一种思路:用1组26个质数代表26个字母,然后对每个字符串进行相乘,乘积相等则为异位词,还需要考虑乘积越界的处理

代码

  1. /**
  2. * @param {string[]} strs
  3. * @return {string[][]}
  4. */
  5. var groupAnagrams = function(strs) {
  6. let map = new Map();
  7. for(let i = 0; i < strs.length; i ++) {
  8. let cur = strs[i];
  9. let curStr = cur.split('').sort().join('')
  10. if (map.has(curStr)) {
  11. let val = map.get(curStr)
  12. map.set(curStr, [...val, cur])
  13. } else {
  14. map.set(curStr, [cur])
  15. }
  16. }
  17. return [...map.values()]
  18. };

复杂度分析

时间复杂度 字符的统计 - 图9#card=math&code=O%28N%5E2logN%29)
空间复杂度 字符的统计 - 图10#card=math&code=O%28N%29)

451. 根据字符出现频率排序

思路

先用map存储key-count,然后再对count倒序排序再拼接

代码

  1. var frequencySort = function(s) {
  2. let obj = buildTargetObject(s);
  3. const arr = getTargetSort(obj);
  4. return buildStr(arr)
  5. };
  6. function buildTargetObject(str) {
  7. const obj = {}
  8. for(let i = 0; i < str.length; i ++) {
  9. let cur = str[i];
  10. obj[cur] = (obj[cur] || 0) + 1
  11. }
  12. return obj
  13. }
  14. function getTargetSort(obj) {
  15. const arr = Object.entries(obj)
  16. return arr.sort((a, b) => b[1] - a[1])
  17. }
  18. function buildStr(arr) {
  19. let str = '';
  20. for(let i = 0; i < arr.length; i ++) {
  21. let [key, value] = arr[i]
  22. str += key.repeat(value)
  23. }
  24. return str
  25. }

复杂度分析

时间复杂度 字符的统计 - 图11#card=math&code=O%28NlogN%29)
空间复杂度 字符的统计 - 图12#card=math&code=O%28N%29)

423. 从英文中重建数字

657. 机器人能否返回原点

思路

用map存储 key-count,然后判断L和R,U和D是否相等

代码

  1. /**
  2. * @param {string} moves
  3. * @return {boolean}
  4. */
  5. var judgeCircle = function(moves) {
  6. let obj = {}
  7. for(let i = 0; i < moves.length; i ++) {
  8. let cur = moves[i];
  9. obj[cur] = (obj[cur] || 0) + 1
  10. }
  11. return obj['U'] === obj['D'] && obj['L'] === obj['R']
  12. };

复杂度分析

时间复杂度 字符的统计 - 图13#card=math&code=O%28N%29)
空间复杂度 字符的统计 - 图14#card=math&code=O%28N%29)

551. 学生出勤记录 I

思路

记录A 和 L的次数,看看是不是符合要求

代码

  1. /**
  2. * @param {string} s
  3. * @return {boolean}
  4. */
  5. var checkRecord = function(s) {
  6. let aCount = 0, lCount = 0, aFlag = 0, lFlag = 0, visitLast = false, len = s.length;
  7. for(let i = 0; i < len - 1; i ++) {
  8. if (s[i] === 'A') {
  9. aCount += 1;
  10. }
  11. if (s[i] === 'L') {
  12. lCount = 1;
  13. while(s[i] === s[i+1]) {
  14. lCount += 1;
  15. i ++;
  16. if (i === len - 1) {
  17. visitLast = true
  18. }
  19. if (lCount >= 3) {
  20. lFlag = 1
  21. }
  22. }
  23. }
  24. }
  25. if (!visitLast && s[len - 1] === 'A') {
  26. aCount += 1;
  27. }
  28. if (aCount > 1) {
  29. aFlag = 1
  30. }
  31. return (aFlag + lFlag) < 1
  32. };

复杂度分析

时间复杂度 字符的统计 - 图15#card=math&code=O%28N%29)
空间复杂度 字符的统计 - 图16#card=math&code=O%281%29)

696. 计数二进制子串

467. 环绕字符串中唯一的子字符串

535. TinyURL 的加密与解密