快乐数 // 「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和, //然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。 //非快乐数 肯定要无限循环,就算说求和过程中,和会重复出现。就可以利用哈希进行抉择 var happyNum = function (num) { resSet = new Set(); //计算sum的值 const getSum = function (num) { var sum = 0; var temp = num; //计算各位上的平方和 while (temp != 0) { let digits = temp % 10; sum += digits * digits temp = parseInt(temp / 10) } return sum } let flag = true while (flag) { let sum = getSum(num) console.log("sum", sum) //如果sum==1 符合条件返回 if (sum == 1) { return true } //如果sum的值重复了 就不符合条件 if (resSet.has(sum)) { return false } //将sum存入Set中,判断是否存在 resSet.add(sum) //将算出的总数再次进入循环 num = sum; } } console.log(happyNum(32))
两个数组的交集 var intersection = function (nums1, nums2) { //把大的数组放在nums1 if (nums1.length < nums2.length) { let _ = nums1; nums1 = nums2; nums2 = _; } let nums1Set = new Set(nums1); let resSet = new Set(); for (let i = 0; i < nums2.length; i++) { if (nums1Set.has(nums2[i])) { resSet.add(nums2[i]) } } console.log(resSet) //如果返回结果要数组类型 Array.from // console.log(Array.from(resSet)) } nums1 = [1, 2, 3, 5, 2, 1] nums2 = [2, 2, 5, 6, 1] intersection(nums1, nums2)
两数之和,返回下标 // 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 // 两个 整数,并返回他们的数组下标。 var twoSum = function (nums, target) { var hash = { }; for (i = 0; i < nums.length; i++) { if (hash[target - nums[i]] !== undefined) { return [i, hash[target - nums[i]]] } hash[nums[i]] = i } return [] } console.log(twoSum([2, 7, 11, 15], 26))
三数之和 //双指针解法 // 循环内不考虑去重 var threeSum = function (nums) { const len = nums.length; if (len < 3) return []; nums.sort((a, b) => a - b); const resSet = new Set(); for (let i = 0; i < len - 2; i++) { if (nums[i] > 0) break; let l = i + 1, r = len - 1; while (l < r) { const sum = nums[i] + nums[l] + nums[r]; if (sum < 0) { l++; continue }; if (sum > 0) { r--; continue }; resSet.add(`${ nums[i]},${ nums[l]},${ nums[r]}`); l++; r--; } } return Array.from(resSet).map(i => i.split(",")); };
赎金信 // 给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false。 // (题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。) var canConstruct = function (ransom, magazine) { //创建一个24位存放字母的数组 var resArr = new Array(24).fill(0, 0, 24) const base = a.charCodeAt() for (item of magazine) { let itemCode = item.charCodeAt() resArr[itemCode - base]++ } for (item of ransom) { let itemCode = item.charCodeAt() resArr[itemCode - base]-- if (resArr[itemCode - base] < 0) { return false } } return true } console.log(canConstruct(asdvasd, aaab))
有效的字母异位词 //数组长度明确时,可以使用数组充当哈希表 var isAnagram = function (firstArr, lastArr) { if (firstArr.length != lastArr.length) { return false } //先定义一个用来储存出现次数的数组 let record = new Array(24).fill(0, 0, 24) let base = a.charCodeAt(); console.log(record) for (item of firstArr) { let itemCode = item.charCodeAt() let i = itemCode - base; record[i]++ } for (item of lastArr) { let itemCode = item.charCodeAt() let i = itemCode - base; record[i]-- } for (item of record) { if (item != 0) { return false } } return true } let s = "anagram"; let t = "nagaram"; console.log(isAnagram(s, t))