function generate(a,l){
if(a.length < l) return '老数组长度不足!';
/*a长度可能超出,可以生成新数组后截取长度为l的赋值给b,也可以生成为l的b(这里选第二种)*/
var i=0, tmp=[], b=[];
// 每次获取a的一个随机元素,同时将
while(i
function Stack() {
this.dataStore = [];
this.top = 0;//栈顶元素的位置
this.push = push;
this.pop = pop;
this.peek = peek;
this.length=length;
this.clear=clear;
}
function push(element) {//进栈
this.dataStore[this.top++] = element;
}
function pop() {//出栈
return this.dataStore[--this.top];
}
function peek() {//栈顶元素
return this.dataStore[this.top-1];
}
function length() {
return this.top;
}
function clear() {
this.top = 0;
}
//测试栈的实现
var s= new Stack();
s.push("D");
s.push("R");
s.push("B");
console.log(s.length());
console.log(s.peek());
console.log(s.clear());
console.log(s.length());
function num(arr){
var str=arr.join('');
var res=[];
for(var i=0;i
function max(str){
//字典序从小到大:abcdefg......
var arr=str.split('');
var res=[arr[arr.length-1]];//字符串最后一个元素肯定符合条件
for(var i=arr.length-2;i>=0;i--){//从倒数第二个元素开始,找单调递增的元素
if(arr[i]>=res[0]){
res.unshift(arr[i]);//找到符合的直接加入到res中
}
}
return res.join('');
}
var str='abddaa';
console.log(max(str));
function Mirror(root){
if(root==null){//当一开始根节是空的时候,返回false
return false;
}
if(root.left ==null && root.right ==null){//当只有一个根节点时返回false
return false;
}
//第三种情况:当左右子树不为空的时候,交互左右子树节点
var temp=root.left;
root.left=root.right;
root.right=temp;
if(root.left!=null){//递归遍历左子树
Mirror(root.left);
}
if(root.right!=null){//递归遍历右子树
Mirror(root.right);
}
}
function printMatrix(matrix)
{
// write code here
var row1 = 0;
var row2 = matrix.length-1;
var col1 = 0;
var col2 = matrix[0].length-1;
var rowflag = 1;
var colflag = 1;
var list=[];
while(row2>=row1 && col2>=col1){
if(rowflag == 1){
for(var i=col1; i<=col2; i++)
list.push(matrix[row1][i]);
row1++;
}
if(colflag == 1){
for(var i=row1; i<=row2; i++)
list.push(matrix[i][col2]);
col2--;
}
if(rowflag == -1){
for(var i=col2; i>=col1; i--)
list.push(matrix[row2][i]);
row2--;
}
if(colflag == -1){
for(var i=row2; i>=row1; i--)
list.push(matrix[i][col1]);
col1++;
}
rowflag = rowflag*(-1);
colflag = colflag*(-1);
}
return list;
}
function Fibnacci(n){
var res=[0,1];
if(n<2){
return res[n];
}
var fib1=0;
var fib2=1;
var fibn=0;
for(var i=2;i<=n;i++){
fibn=fib1+fib2;
fib1=fib2;
fib2=fibn;
}
return fibn;
}
function jumpFloor(number)
{
if(number ===0){
return 0;
}
if(number===1){
return 1;
}
if(number ===2){
return 2;
}
var one = 1;
var two = 2;
var num = 0;
for(let i=3;i<=number;i++){
num = one + two;
one = two;
two = num;
}
return num
}
function Find(target, array) {
//从最右上角开始确定一个点开始比较
let i = 0;
let j = array[i].length - 1;//将最右边的列作为定点
while (i < array.length && j >= 0) {
if (array[i][j] < target) {
i++;
} else if (array[i][j] > target) {
j--;
} else {
return true;
}
}
return false;
}
方法1:
function MoreThanHalfNum_Solution(numbers)
{
// write code here
if(numbers==null){
return null;
}
var string=numbers.join('');
var len=Math.floor(numbers.length/2);
for(var i=0;ilen){
return numbers[i];
break;
}
}
return 0;
}
function MoreThanHalfNum_Solution(numbers)
{
// write code here
var len=numbers.length;
if(len==0)return 0;
var num=numbers[0];
count=1;
for(var i=0;ilen)return num;
return 0;
}
//借助两个数组arr1和arr2,arr1用来保存按链表顺序压栈,arr2用来保存arr1出栈的元素序列
function printListFromTailToHead(head)
{
// write code here
if(head==null){
return [];
}
var arr1=[];
var arr2=[];
var p=head;
while(p!=null){//首先将元素压入栈
arr1.push(p.val);
p=p.next;
};
while(arr1.length>0){//将arr1里面的元素依次pop到arr2中
arr2.push(arr1.pop());
}
return arr2;
}
function reConstructBinaryTree(pre, vin)
{
// write code here
var root=pre[0];
if(pre.length==0||vin.length==0){
return false;
}
for(var i=0;i
function minNumberInRotateArray(rotateArray)
{
// write code here
if (array == null || array.length == 0) {//当输入的是0或者是空的时候
return 0;
}
if (array.length == 1 || array[array.length - 1] > array[0]) {
//当输入的是一个元素或者是单调递增的
return array[0];
}
var start = 0;
var end = array.length - 1;
while (start < end) {
var mid = parseInt((end - start) / 2 + start);
if (array[mid] == array[end]) {
end--;
} else if (array[mid] < array[end]){
end = mid;
} else {
start = mid + 1;
}
}
return array[start];
}
方法一:
function FindKthToTail(head, k)
{
// write code here
if(head==null){
return null;
}
var res=[];
var len=0;
var p=head;
while(p!=null){
res.push(p);
p=p.next;
}
return res[res.length-k];
}
方法二:
function FindKthToTail(head, k) {
// write code here
if( head==null|| k==0 ){
return false;
}
var p1=head;
var p2=null;
for( var i=0;i
/*function ListNode(x){
this.val = x;
this.next = null;
}*/
function ReverseList(pHead)
{
// write code here
if(pHead==null){
return null;
}
var arr=[];
var p1=pHead;
while(p1!=null){
arr.push(p1);
p1=p1.next;
//数组里面装的是节点类型的元素
}
//console.log(arr.length);
var p2Head=arr.pop();
var p2=p2Head;
var pre=p2Head;//用来重新连接的指针
while(arr.length>0){
p2=arr.pop();
pre.next=p2;
pre=p2;
}
pre.next=null;//最后给最后一个元素的next置为空
return p2Head;
}
module.exports = {
ReverseList : ReverseList
};
function ListNode(x){
this.val = x;
this.next = null;
}
function Merge(pHead1, pHead2)
{
// write code here
var p1=pHead1;
var p2=pHead2;
var pHead3=new ListNode(-1);//自己定义一个头结点
var p3=pHead3;
while(p1!=null && p2!=null){
if(p1.val<=p2.val){
p3.next=p1;
p3=p1;
p1=p1.next;
continue;//如果走到最后一个,不能再进行下面的判断,因为没有val值
}
if(p1.val>p2.val){
p3.next=p2;
p3=p2;
p2=p2.next;
}
}
while(p1!=null){
p3.next=p1;
p3=p1;
p1=p1.next;
}
while(p2!=null){
p3.next=p2;
p3=p2;
p2=p2.next;
}
return pHead3.next;
}
module.exports = {
Merge : Merge
};
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
function Mirror(root)
{
// write code here
if(root==null){
return null;
}
if(root.left==null&&root.right==null){
return root;
}
//前序遍历 用后序遍历也可以
var temp=root.left;
root.left=root.right;
root.right=temp;
Mirror(root.left);
Mirror(root.right);
}
解题思路:利用一个队列进行层次遍历,先把一个节点放到队列中,然后再利用这个结点把它的左子结点和右子结点放到队列中;然后再把该节点放到打印数组中;循环的条件是队列不为空
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
function PrintFromTopToBottom(root)
{
// write code here
// write code here层序遍历,是先判断元素的左右子树,再将头节点出队列
var queue=[];
var res=[];
if(root!=null){//先判断第一个不为空时把节点加入到队列中
queue.push(root);
}
while(queue.length!=0){//开始判断一下队列的元素
var node=queue.shift();
if(node.left!=null){//先判断下有没有左右子树,有的话先把左右子树节点加入到队列
queue.push(node.left);
}
if(node.right!=null){
queue.push(node.right);
}
res.push(node.val);
}
return res;
}
module.exports = {
PrintFromTopToBottom : PrintFromTopToBottom
};
function FindNumbersWithSum(array, sum)
{
// write code here
if(array==null){
return null;
}
var left=0;
var right=array.length-1;
var curNum=0;
var mulSum;
var result=[];
var min=Number.POSITIVE_INFINITY;
var index1;
var index2;
var flag=false;
while(leftmulSum){
min=mulSum;
index1=left;
index2=right;
}
left++;
right--;
}
if(curNumsum){
right--;
}
}
if(flag==true){
result.push(array[index1]);
result.push(array[index2]);
return result;
}
return [];
}
function FindNumbersWithSum(array, sum)
{
// write code here
if(array==null){
return null;
}
var left=0;
var right=array.length-1;
var curNum=0;
var mulSum;
var result=[];
var min=Number.POSITIVE_INFINITY;
var index1;
var index2;
var flag=false;
while(leftmulSum){
min=mulSum;
index1=left;
index2=right;
}
left++;
right--;
}
if(curNumsum){
right--;
}
}
if(flag==true){
result.push(array[index1]);
result.push(array[index2]);
return result;
}
return [];
}
var list = [1,2,[3,4],[5,6,[7,8],9],10,11]
var res = [];
function flatten(list, depth){
if(depth == 0){
for(var i = 0; i
方法1:先排序,然后将第一个元素先放进结果数组中,从第二个起循环遍历数组,每次都和结果数组的最后一个元素比较。
function del(arr){
var arr=arr.sort();
var res=[arr[0]];//把第一个元素取出来
for(var i=0;i
方法2:使用indexof方法
function del(arr){
var res=[];
for(var i=0;i
方法3:使用set()方法
function quchong(arr){
const s=new Set(arr);
console.log(s);
}
var arr=[1,3,2,4,2,5,2,5];
quchong(arr);
1判断是否有环
2,找环的入口
原理:从链表起点head开始到入口点的距离a,与从slow和fast的相遇点到入口点的距离相等。(别人推导出来的)
3 如果存在环,求环上的节点数
记录下相遇时的节点,并且存入临时变量temp中,然后慢指针继续往下走slow=slow.next,一直到slow=temp,此时经过的步数就是环的长度。
4 如果存在环,求出链表的长度
解决思路:链表的长度=起点到入口的距离+环的长度
5 求出一个环上距离任意一个节点最远的点
问题:构建乘积数组
将数组B分开,分成左下三角和右上三角;左下三角c[i]=c[i-1]*A[i-1].右上三角 D[i]=D[i+1]*A[i+1];
用当前cur指针和pre前驱指针,当两者相邻的时候说明cur还没有找到重复元素,不相邻的时候说明pre和cur之间有了部分相同的元素。
function ListNode(x){
this.val = x;
this.next = null;
}
function deleteDuplication(pHead)
{
// write code here
if(pHead==null){
return null;
}
var node=new ListNode(-1);
node.next=pHead;
var pre=node;
var cur=node.next;
while(cur!=null){
while(cur.next!=null && cur.val==cur.next.val){//一定要注意cur.next!=null
cur=cur.next;
}
if(pre.next!=cur){//cur找到重复元素往后移动了,才不和Pre挨着了
pre.next=cur.next;
cur=cur.next;
}else{//当还没遇到重复元素时,既pre 和cur还挨着的时候
pre=cur;//只有先让pre移动到cur,cur再移动,才能保证pre永远比cur慢一步
cur=cur.next;
}
}
return node.next;
}
该题的解题思路就是:
分两种情况:1.该节点有右子树,则右子树的最最左结点是所要找的节点
2.该节点没有右子树,则一直往上找,直到找到一个结点是其父结点的左子结点,则该父结点就是所要找的节点
/*function TreeLinkNode(x){
this.val = x;
this.left = null;
this.right = null;
this.next = null;
}*/
function GetNext(pNode)
{
// write code here
//分三种情况:
//1.当该节点有右子树,则右子树的最左子节点是所要找的节点
//2.当该节点没有右子树,则找当前节点是其父节点的左子结点的节点
if(pNode==null){
return null;
}
if(pNode.right!=null){//情况1
var pNode=pNode.right;
while(pNode.left!=null){
pNode=pNode.left;
}
return pNode;
}
while(pNode.next!=null){//情况2
if(pNode.next.left==pNode){
return pNode.next;
}
pNode=pNode.next;
}
}
function isSymmetrical2(root1,root2){
if(root1 == null && root2 == null){
return true;
}
if(root1 == null || root2 == null){
return false;
}
if(root1.val != root2.val){
return false;
}
return isSymmetrical2(root1.left,root2.right) && isSymmetrical2(root1.right,root2.left);
}
function isSymmetrical(pRoot)
{
// write code here
return isSymmetrical2(pRoot,pRoot);
}
解题思路:使用两个栈来操作,stack1用来暂存奇数行的节点,stack2用来暂存偶数行的节点。当奇数行的时候,将奇数行元素加入结果数组的同时,还把下一行的元素按照先左子节点后右子节点的顺序加入到stack2中;当偶数行的时候,将偶数行元素加入结果数组的同时,还把下一行的元素按照先右子节点后左子节点的顺序加入到stack1中;
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
function Print(pRoot)
{
// write code here
var lists=new Array();//存放结果
if(pRoot==null){
return lists;
}
var stack1=[];//存放奇数行
var stack2=[];//存放偶数行
stack1.push(pRoot);
var i=1;//层数
while(stack1.length!=0 || stack2.length!=0){
var list=new Array();
if((i&1)==1){//当是奇数行的时候
while(stack1.length!=0){
var temp=stack1[stack1.length-1];//用一数组记录下,一直是从后往前push的
list.push(temp.val);
stack1.pop();
if(temp.left!=null){
//把下一行(偶数行)的数保存在stack2中,因为是从右往左,所以在栈中先添加左子节点
stack2.push(temp.left);
}
if(temp.right!=null){
stack2.push(temp.right);
}
}
}else{//当是偶数行的时候
while(stack2.length!=0){
var temp=stack2[stack2.length-1];
list.push(temp.val);
stack2.pop();
//因为奇数行是从左往右打印,所以在栈中先添加右子节点再添加左子节点
if(temp.right!=null){
stack1.push(temp.right);
}
if(temp.left!=null){
stack1.push(temp.left);
}
}
}
i++;
lists.push(list);
}
return lists;
}
解题思路: 在层序遍历+队列的基础上,判断每层的节点数;先把每层的节点放进数组中,然后再把这个数组放在结果数组中。
function Print(pRoot)
{
// write code here
if(pRoot==null){
return [];
}
var queue=[];
var res=[];
queue.push(pRoot);
while(queue.length!=0){
var len=queue.length;//一定要在这个地方标记一下queue的长度,以免queue添加的时候篡改
var tempArr=[];//用来临时保存一行的元素
for(var i=0;i
解题思路:先将一个棵树深度遍历(前序遍历)到一个数组,其中将'a’作为树的叶子节点;然后再前序遍历反序列化
function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
}
let arr=[]
function Serialize(pRoot)
{
// write code here
if(pRoot!=null){//深度优先遍历
arr.push(pRoot.val);
Serialize(pRoot.left);
Serialize(pRoot.right);
}else{
arr.push('a');//把a当做叶子节点
}
}
function Deserialize()
{
// write code here
var root=null;
if(arr.length<0){
return null
};//接上一种情况,当arr里没有元素的时候
let node=arr.shift();
if(typeof node == 'number'){
root=new TreeNode(node);//将摘下来的node传给一个树节点
root.left=Deserialize();
root.right=Deserialize();
}
return root;
}
问题30 给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
解题思路:中序遍历+计数。
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
function KthNode(pRoot, k)
{
// write code here
if(pRoot==null || k==0){
return null;
}
function KthNodeCore(pRoot){//对这个函数进行递归
let target = null;//目标值
if(pRoot.left != null){ //中序遍历先遍历左子树
target = KthNodeCore(pRoot.left, k);
}
if(target == null){//当左子树遍历不到的时候,遍历根节点
if(k == 1){//k等于1说明找到了
target = pRoot;
}
k--;
}
if(target == null && pRoot.right != null){//当左子树和根都没有找到的话,遍历右子树
target = KthNodeCore(pRoot.right, k);
}
return target;
}
return KthNodeCore(pRoot);
}
问题:数组中重复的数字
由于数组里的所有数字都在0到n-1,也就是值也在数组的下标范围里。
我们可以这样做,通俗来讲,就是把数组中的每个值放到对应的下标的位置上。(数归其标)
function duplicate(numbers, duplication)
{
// write code here
//这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
//函数返回True/False
for(var i=0;i