前 K 个高频元素
问题描述: 给你一个整数数组 nums
和一个整数 k
,请你返回其中出现频率前 k
高的元素。你可以按 任意顺序 返回答案。(by leetcode 347)
示例 :
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
思路-桶排序:
① 首先遍历得出每个元素出现的次数,
② 然后建立数组,数组下标是次数,值对应元素值。(其实是把桶放到指定下标位置,桶里面的元素个数不一定)
③ 从数组最后的下标开始找元素,找前k个有元素值的元素返回。
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var topKFrequent = function(nums, k) {
let map=new Map;
// 第一步
for(let i=0;i<nums.length;i++){
if(map.get(nums[i])){
map.set(nums[i],map.get(nums[i])+1)
}else{
map.set(nums[i],1)
}
}
//第二步
let arr=[];
for(let [key,value] of map){
if(arr[value]&&arr[value].length){
arr[value].push(key)//对应位置已有桶,直接放值
}else{
arr[value]=[key]//摆放桶,并放值
}
}
//第三步
let newarr=[],count=0;
for(let i=arr.length;i>0&&count<k;i--){
if(arr[i]){//保证桶里有值
newarr=newarr.concat(arr[i]);
count+=arr[i].length
}
}
return newarr;
};
二叉树的直径
问题描述: 给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。(by leetcode 534)
示例 :
给定二叉树
1
/ \
2 3
/ \
4 5
返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。
思路:
最长深度优先(这个概念后面补充)
用递归,递归函数返回的是每个节点中,左右节点中最长的那颗子树的直径。
算出每个节点左右子树相加最长的路径是多少,作为节点值。从最叶节点开始算起,往上的节点值就是叶节点的值相加。
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var diameterOfBinaryTree = function(root) {
var ans=0;
var depth=function(root){
if(root==null) return 0;
let l=depth(root.left)//当前节点左子树最长直径
let r=depth(root.right)//当前节点右子树最长直径
ans=Math.max(ans,l+r);//经过当前节点的最长直径跟之前的最大值比较。
return Math.max(l,r)+1//该节点向上链接父节点,所以直径加1,max中取出来的值代表要连接那颗子树
}
depth(root);
return ans
};
最长回文串
问题描述: 给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。(by leetcode 409)
在构造过程中,请注意区分大小写。比如 "Aa"
不能当做一个回文字符串。
注意: 假设字符串的长度不会超过 1010。
示例 1:
输入:
"abccccdd"
输出:
7
解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。
思路:
用Set管理,偶数的删除,奇数最多一个。(找到回文串的特点即可知道)
/**
* @param {string} s
* @return {number}
*/
var longestPalindrome = function(str) {
let set=new Set()
let arr=str.split("");
console.log(arr)
let num=0;
for(let i=0;i<arr.length;i++){
if(set.has(arr[i])){
set.delete(arr[i]);
num+=2;
}else{
set.add(arr[i])
}
}
if(set.size){
num++
}
return num
};
最长递增子序列
问题描述: 给你一个整数数组 nums
,找到其中最长严格递增子序列的长度。
子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7]
是数组 [0,3,1,6,2,2,7]
的子序列。(by leetcode)
示例 1:
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
思路:
动态规划 直接上代码吧,注释先放到代码里面哦~
/**
* @param {number[]} nums
* @return {number}
*/
var lengthOfLIS = function(nums) {
if(!nums.length){
return nums
}
let long=[];//用来存储对应位置到之前的最长递增
let ins=1;
for(let i=0;i<nums.length;i++){
long[i]=1;//默认经过本身,所以是1
for(let j=0;j<i;j++){
if(nums[j]<nums[i]){
long[i]=Math.max(long[i],long[j]+1)//如果当前值比之前某个值大,说明可以排在那个值后面,所以要看那个值的long高(加1是因为要加上当前值)还是本身的高
}
}
ins=Math.max(ins,long[i])//往后循环找最大值,也就是最长递增序列长度
}
return ins
};
排序数组
问题描述: 给你一个整数数组 nums
,请你将该数组升序排列。(by leetcode 912)
示例 1:
输入:nums = [5,2,3,1]
输出:[1,2,3,5]
思路:
采用二路归并排序 采用分治的思想 先排小的,再排大的,也是用递归的形式
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortArray = function(nums) {
partSort(nums,0,nums.length-1)
return nums
};
var partSort=function(num,l,r){
if(l>=r)return false;
let mid=Math.floor((r+l)/2);
partSort(num,l,mid)//排左边 同时修改了内部的值
partSort(num,mid+1,r)//排左边
let i=l,j=mid+1;//增加两个指针,用于找到最小值
let temp=[];
while(i<=mid&&j<=r){
if(num[i]<=num[j]){
temp.push(num[i])
i++
}else{
temp.push(num[j])
j++
}
}
while(i<=mid){
temp.push(num[i])
i++;
}
while(j<=r){
temp.push(num[j])
j++;
}
//用排好的临时数组修改本身的值
for (let i = 0; i < temp.length; ++i) {
num[i + l] = temp[i];
}
}