NC45 实现二叉树先序,中序和后序遍历
描述
给定一棵二叉树,分别按照二叉树先序,中序和后序打印所有的节点。
数据范围:0 \le n \le 10000≤n≤1000,树上每个节点的val值满足 0 \le val \le 1000≤val≤100
要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)
样例解释:
示例1
输入:
{1,2,3}
返回值:
[[1,2,3],[2,1,3],[2,3,1]]
说明:
如题面图
示例2
输入:
{}
返回值:
[[],[],[]]
备注:
n \leq 10^6n≤106
代码:
/*
* function TreeNode(x) {
* this.val = x;
* this.left = null;
* this.right = null;
* }
*/
/**
*
* @param root TreeNode类 the root of binary tree
* @return int整型二维数组
*/
function threeOrders( root ) {
// write code here
let res=[];
let pre=[];
let preOrder=((root)=>{
if(root==null)
return null;
pre.push(root.val);
preOrder(root.left);
preOrder(root.right);
})
preOrder(root);
res.push(pre);
let In=[];
let InOrder=((root)=>{
if(root==null)
return null;
InOrder(root.left);
In.push(root.val);
InOrder(root.right);
});
InOrder(root);
res.push(In);
let post=[];
let postOrder=((root)=>{
if(root==null)
return null;
postOrder(root.left);
postOrder(root.right);
post.push(root.val);
});
res.push(post);
postOrder(root)
return res;
}
module.exports = {
threeOrders : threeOrders
};
NC119 最小的K个数
描述
给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。
数据范围:0\le k,n \le 100000≤k,n≤10000,数组中每个数的大小0 \le val \le 10000≤val≤1000
要求:空间复杂度 O(n)O(n) ,时间复杂度 O(nlogn)O(nlogn)
示例1
输入:
[4,5,1,6,2,7,3,8],4
返回值:
[1,2,3,4]
说明:
返回最小的4个数即可,返回[1,3,2,4]也可以
示例2
输入:
[1],0
返回值:
[]
示例3
输入:
[0,1,2,1,2],3
返回值:
[0,1,1]
代码:
function GetLeastNumbers_Solution(input, k)
{
// write code here
input.sort(function(a,b){
return a-b;
});
let arr=input.slice(0,k);
return arr;
}
module.exports = {
GetLeastNumbers_Solution : GetLeastNumbers_Solution
};
NC15 求二叉树的层序遍历
描述
给定一个二叉树,返回该二叉树层序遍历的结果,(从左到右,一层一层地遍历)
例如:
给定的二叉树是{3,9,20,#,#,15,7},
该二叉树层序遍历的结果是
[
[3],
[9,20],
[15,7]
]
数据范围:二叉树的节点数满足 1 \le n \le 10^5 \1≤n≤105
示例1
输入:
{1,2}
返回值:
[[1],[2]]
示例2
输入:
{1,2,3,4,#,#,5}
返回值:
[[1],[2,3],[4,5]]
代码:
/*
* function TreeNode(x) {
* this.val = x;
* this.left = null;
* this.right = null;
* }
*/
/**
*
* @param root TreeNode类
* @return int整型二维数组
*/
function levelOrder( root ) {
// 最外层数组存储
let res=[];
// q存储层的节点
let q=[];
// 将根节点存入q中
q.push(root);
// 判断q当前的长度是否为0,如果为0则层序遍历结束
while(q.length!=0){
// 存储当前q的长度
let currentlength=q.length;
// 给存储数组推入一个空数组
res.push([]);
// 循环遍历当前层的节点
for(let i=0;i<currentlength;i++){
// 弹出q内的节点
let node=q.shift();
// 将节点值存入res新加入的数组中
res[res.length-1].push(node.val);
// 判断当前节点是否有左孩子
if(node.left!=null)
// 有则向q推入下层节点
q.push(node.left);
// 同上
if(node.right!=null)
q.push(node.right);
}
}
return res;
}
module.exports = {
levelOrder : levelOrder
};
NC88 寻找第K大
描述
有一个整数数组,请你根据快速排序的思路,找出数组中第 k 大的数。
给定一个整数数组 a ,同时给定它的大小n和要找的 k ,请返回第 k 大的数(包括重复的元素,不用去重),保证答案存在。
要求:时间复杂度 O(nlogn)O(nlogn),空间复杂度 O(1)O(1)
数据范围:0\le n \le 10^50≤n≤105, 1 \le K \le n1≤K≤n,数组中每个元素满足 0 \le val \le 10^90≤val≤109
示例1
输入:
[1,3,5,2,2],5,3
返回值:
2
示例2
输入:
[10,10,9,9,8,7,5,6,4,3,4,2],12,3
返回值:
9
说明:
去重后的第3大是8,但本题要求包含重复的元素,不用去重,所以输出9
代码:
/**
*
* @param a int整型一维数组
* @param n int整型
* @param K int整型
* @return int整型
*/
function findKth( a , n , K ) {
// write code here
a.sort(function(x,y){
return y-x;
})
return a[K-1];
}
module.exports = {
findKth : findKth
};
NC50 链表中的节点每k个一组翻转
描述
将给出的链表中的节点每 k 个一组翻转,返回翻转后的链表
如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。
数据范围: \ 0 \le n \le 2000 0≤n≤2000 , 1 \le k \le 20001≤k≤2000 ,链表中每个元素都满足 0 \le val \le 10000≤val≤1000
要求空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)
例如:
给定的链表是 1\to2\to3\to4\to51→2→3→4→5
对于 k = 2k=2 , 你应该返回 2\to 1\to 4\to 3\to 52→1→4→3→5
对于 k = 3k=3 , 你应该返回 3\to2 \to1 \to 4\to 53→2→1→4→5
示例1
输入:
{1,2,3,4,5},2
返回值:
{2,1,4,3,5}
示例2
输入:
{},1
返回值:
{}
方法一(利用堆栈)
/*
* function ListNode(x){
* this.val = x;
* this.next = null;
* }
*/
/**
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
function reverseKGroup( head , k ) {
// write code here
// 方法一(堆栈)
// arr存储节点
let arr=[],p1=head,p2=null;
// 定义head1存储新链表
let head1=new ListNode(null),count=0,p,sum=0;
// 令p指向head1
p=head1;
// 计算链表长度
while(p1){
count++;
p1=p1.next;
}
// 当链表长度小于k时,直接返回链表
if(count<k){
return head;
}
let x=k;
// 遍历链表
for(let i=0;i<count;i++){
// 重新给x赋值k个步长
x=k;
// 遍历k个步长
while(x){
// 将head.next暂存在p1中
p1=head.next;
// 取出head的第一个节点
head.next=null;
// 将第一个节点赋值给p2;
p2=head;
// 将节点推入栈中
arr.push(p2);
// 重新给head赋值回p1;
head=p1;
// 步数减一
x--;
// 总数加一
sum++;
}
// 重新给x赋值k个步长
x=k;
while(x){
// 使p节点的next指向arr弹出的节点,使head1.next指向arr弹出的节点
p.next=arr.pop();
// 使head1向后移动
p=p.next;
x--;
}
// 链表长度减去总数小于k时直接将剩余的head赋值给head1,并退出循环
if(count-sum<k){
p.next=head;
break;
}
}
head1=head1.next;
return head1;
}
方法二(与方法一类似)
function reverseKGroup( head , k ) {
// 方法二(与堆栈类似)
let p1=head,p2=null
let head1=new ListNode(null),count=0,sum=0;
let p=head1;
// 计算head长度
while(p1){
count++;
p1=p1.next;
}
if(count<k){
return head;
}
sum=count;
let x=k;
for(let i=0;i<count;i++){
x=k;
p2=null;
// 反转k个步长的链表,并存储在p2中
while(x){
p1=head.next;
head.next=p2;
p2=head;
head=p1;
x--;
}
// 使节点p的next指向p2,head1中添加上p2
p.next=p2;
x=k;
// 使p向后移动k个步长,至head1末尾
while(x){
p=p.next;
x--;
}
// 总数减去k个步长
sum=sum-k;
// 当总数小于k个步长时,直接将剩余的head接入head1中
if(sum<k){
p.next=head;
break;
}
}
return head1.next;
}
方法三(大部分人的做法)
function reverseKGroup( head , k ) {
let pre = null
let current = head
let node = head
for(let i = 0;i < k;i++) {
if(node === null) {
return head
}
node = node.next
}
for(let i = 0;i < k;i++) {
let t= current.next
current.next = pre
pre = current
current = t
}
head.next = reverseKGroup(current,k)
return pre
}