前端开发人员一般都会被其他端的开发人员认为并不是真正合格的程序员,原因在于:前端只需要了解简单的html和css就可以进行开发,就是是学习javascript也只是一种弱类型的语言,和java这种强类型的语言相比,还是差了很多。
其实,前端开发人员同样是可以做很多事情的,且不说javascript目前可以用于node.js,人工智能,物联网等方向。就单单算法这部分,前端也是同样可以写出很多优秀的算法的。拿大家使用的比较多的一本书<剑指offer>为例:
1.二维数组的查找
function Find(target, array)
{
// write code here
var row = array.length; // 行数
var col = array[0].length; // 列数
// 从右上角开始比较
var r = 0;
var c = col-1;
while(r <=row-1 && c >= 0) { // 注意这里有等于号
if (target > array[r][c]) {
r++;
}
else if (target < array[r][c]) {
c--;
}
else {
return true;
}
}
return false;
}
2.替换空格
function replaceSpace(str)
{
// write code here
return str.replace(/\s+?/g,'%20')
}
3.从尾到头打印链表
function printListFromTailToHead(head)
{
// write code here
var res = [];
while(head!=null){
res.push(head.val);
head = head.next;
}
return res.reverse();
}
4.重建二叉树
function reConstructBinaryTree(pre, vin)
{
// write code here
if (!pre || pre.length === 0) {
return;
}
var treeNode = {
val: pre[0]
}
for(var i = 0; i < pre.length; i++) {
if (vin[i] === pre[0]) {
treeNode.left = reConstructBinaryTree(pre.slice(1, i+1), vin.slice(0, i));
treeNode.right = reConstructBinaryTree(pre.slice(i+1),vin.slice(i+1));
}
}
return treeNode;
}
5.用两个栈实现队列
var result=[];
function push(node)
{
// write code here
result.push(node)
}
function pop()
{
// write code here
return result.shift()
}
6.旋转数组的最小数字
function minNumberInRotateArray(rotateArray)
{
// write code here
rotateArray.sort(function(a,b){
if(a<b){
return -1;
}
else
return 1;
})
return rotateArray[0];
}
7.斐波那契数列(循环方法)
function Fibonacci(n)
{
// write code here
if(n==0||n==1){
return n;
}
var f1 = 0;
var f2 = 1;
for(var i =2;i<=n;i++){
var tmp = f1 + f2;
f1 = f2;
f2 = tmp;
}
return tmp;
}
8.上楼梯
function jumpFloor(number)
{
// write code here
if(number==1){
return 1;
}
if(number==2){
return 2;
}
var f1 = 1;
var f2 = 2;
for(var i=2;i<number;i++){
var tmp = f1+ f2;
f1 = f2;
f2 = tmp;
}
return f2;
}
9.上楼梯升级
function jumpFloorII(number)
{
// write code here
if(number==1){
return 1;
}
if(number==2){
return 2;
}
else
return 2*jumpFloorII(number-1);
}
10.矩形覆盖
function rectCover(number)
{
// write code here
if(number<=0){
return 0;
}
if(number==1||number==2){
return number;
}
var f1 = 0;
var f2 = 1;
for(var i=1;i<=number;i++){
var tmp = f1 + f2;
f1 = f2;
f2 = tmp;
}
return f2;
}
11.二进制中1的个数
function NumberOf1(n)
{
// write code here
var count = 0;
while(n!=0){
n = n&(n-1);
count++
}
return count;
}
12.数值的整数次方
function Power(base, exponent)
{
// write code here
if(exponent==0){
return 1;
}
var result = 1;
if(exponent>0){
for(var i=1;i<=exponent;i++){
result *= base;
}
return result;
}
if(exponent<0){
exponent = Math.abs(exponent);
for(var i=1;i<=exponent;i++){
result *= base;
}
result = 1/result;
return result;
}
}
13.调整数组元素顺序使奇数位于偶数之前
function reOrderArray(array)
{
// write code here
var result1 = [];
var result2 = [];
for(var i=0;i<array.length;i++){
if(array[i]%2==0){
result1.push(array[i]);
}
else{
result2.push(array[i]);
}
}
return result2.concat(result1);
}
14.链表中倒数第k个结点
function FindKthToTail(head, k)
{
// write code here
if(head==null||k<=0) return null;
var prev = head;
var tail = head;
for(var index=0;index<k-1;index++){
if(tail.next!=null){
tail=tail.next;
}else{
return null;
}
}
while(tail.next!=null){
prev=prev.next;
tail=tail.next;
}
return prev;
}
module.exports = {
FindKthToTail : FindKthToTail
};
15.反转链表
function ReverseList(pHead)
{
// write code here
if(pHead==null||pHead.next==null) return pHead;
var prev=null;
var next=null;
while(pHead!=null){
next=pHead.next;
pHead.next=prev;
prev=pHead;
pHead=next;
}
return prev;
}
module.exports = {
ReverseList : ReverseList
};
16.合并两个排序的链表
function ListNode(x){
this.val = x;
this.next = null;
}
function Merge(pHead1, pHead2)
{
// write code here
var head=new ListNode(0);
var pHead=head;
while(pHead1!=null && pHead2!=null){
if(pHead1.val>=pHead2.val){
head.next=pHead2;
pHead2=pHead2.next;
}else{
head.next=pHead1;
pHead1=pHead1.next;
}
head=head.next;
}
if(pHead1!=null){
head.next=pHead1;
}
if(pHead2!=null){
head.next=pHead2;
}
return pHead.next;
}
module.exports = {
Merge : Merge
};
17.树的子结构
function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
}
function isSubtree(pRoot1,pRoot2){
if (pRoot2 == null) return true;//pRoot2为null,表示子树已经遍历完
if (pRoot1 == null) return false;
if(pRoot1.val==pRoot2.val){
return isSubtree(pRoot1.left,pRoot2.left) && isSubtree(pRoot1.right,pRoot2.right);
}else{
return false;
}
}
function HasSubtree(pRoot1, pRoot2)
{
// write code here
if(pRoot1==null||pRoot2==null) return false;
return isSubtree(pRoot1,pRoot2)||HasSubtree(pRoot1.left,pRoot2)||HasSubtree(pRoot1.right,pRoot2);
}
module.exports = {
HasSubtree : HasSubtree
};
18.二叉树的镜像
function Mirror(root)
{
// write code here
if(root==null) return null;
//首先先将左右节点互换
var tmp = root.left;
root.left=root.right;
root.right=tmp;
//递归
Mirror(root.left);
Mirror(root.right)
}
module.exports = {
Mirror : Mirror
};
19.顺时针打印矩阵
function printMatrix(matrix)
{
// write code here
if(matrix==null || matrix.length==0) return;
var rows = matrix.length;
var cols = matrix[0].length;
var start=0;
var result=[];
while(cols>start*2 && rows>start*2){
//x,y方向边界值
var endX = cols-1-start;
var endY = rows-1-start;
//左到右
for(var i = start;i<=endX;i++){
result.push(matrix[start][i])
}
//上到下
if(start<endY){
for(var i = start+1;i<=endY;i++){
result.push(matrix[i][endX])
}
}
//右到左
if(start<endX && start<endY){
for(var i = endX-1;i>=start;i--){
result.push(matrix[endY][i])
}
}
//下到上
if(start<endX && start<endY-1){
for(var i = endY-1;i>=start+1;i--){
result.push(matrix[i][start])
}
}
start++
}
return result;
}
module.exports = {
printMatrix : printMatrix
};
20.包含min函数的栈
var result=[]
function push(node)
{
// write code here
return result.push(node)
}
function pop()
{
// write code here
return result.pop()
}
function top()
{
// write code here
return result.length>0?result[result.length-1]:null;
}
function min()
{
// write code here
if(result.length==0||result==null) return;
var min=result[0];
result.map(function(a){
if(a<min){
min=a;
}
})
return min;
}
21.栈的压入,弹出序列
function IsPopOrder(pushV, popV)
{
// write code here
var tmp=[];
for(var i=0,j=0;i<pushV.length;i++){
tmp.push(pushV[i]);
while(tmp.length&&tmp[tmp.length-1]==popV[j]){
tmp.pop();
j++;
}
}
return tmp.length==0;
}
22.从上往下打印二叉树
function PrintFromTopToBottom(root)
{
// write code here
if(root==null) return [];
var result=[];
result.push(root.val);
function travel(root){
if(root.left==null && root.right==null) return;
if(root.left!=null) result.push(root.left.val)
if(root.right!=null) result.push(root.right.val)
if(root.left!=null) travel(root.left);
if(root.right!=null) travel(root.right);
}
travel(root);
return result;
}
23.二叉树的搜索和后续遍历
function VerifySquenceOfBST(sequence)
{
// write code here
if(sequence.length<=0) return;
return test(sequence,0,sequence.length-1)
}
function test(sequence,start,end){
if(start>=end) return true;
var i=end-1;
while(i>=start && sequence[i]>sequence[end]){
i--;
}
for(var j=i;j>=start;j--){
if(sequence[j]>sequence[end]){
return false;
}
}
return test(sequence,start,i)&&test(sequence,i+1,end-1)
}
24.二叉树中和为某一值的路径
function FindPath(root, expectNumber)
{
// write code here
var result=[];
if(root==null) return result;
dfs(root,0,[]);
function dfs(root,current,path){
current+=root.val;
path.push(root.val)
if(current==expectNumber && root.left==null && root.right ==null){
result.push(path.slice(0))
}
if(root.left!=null){
dfs(root.left,current,path)
}
if(root.right!=null){
dfs(root.right,current,path)
}
path.pop()
}
return result;
}
25.复杂链表的复制
function RandomListNode(x){
this.label = x;
this.next = null;
this.random = null;
}
function Clone(pHead)
{
// write code here
if (!pHead) {
return null;
}
// 复制头结点
var node = new RandomListNode(pHead.label);
node.random = pHead.random;
// 递归其他节点
node.next = Clone(pHead.next);
return node;
}
26.二叉搜索树和双向链表
function Convert(pRootOfTree)
{
// write code here
if(pRootOfTree==null){
return null;
}
var lastNode=null;
lastNode=convertNode(pRootOfTree,lastNode);
var head=lastNode;
while(head && head.left){//循环到头部
head=head.left;
}
return head;
}
function convertNode(root,lastNode){
if(root==null) return;
if(root.left){//左子树
lastNode=convertNode(root.left,lastNode)
}
root.left=lastNode;
if(lastNode){
lastNode.right=root;
}
lastNode=root;
if(root.right){//右子树
lastNode=convertNode(root.right,lastNode)
}
return lastNode;
}
27.字符串的排列
function Permutation(str)
{
// write code here
var result=[];
if(str.length<=0){
return [];
}
var sortTemp='';
var arr = str.split('');
result=sortString(arr,sortTemp,[]);
return result
}
function sortString(arr,sortTemp,result){
if(arr.length==0){
result.push(sortTemp)
}else{
var isRepeat={};
for(var i=0;i<arr.length;i++){
if(!isRepeat[arr[i]]){
var temp=arr.splice(i,1)[0];//取出第一个字符
sortTemp+=temp;
sortString(arr,sortTemp,result);
arr.splice(i,0,temp);//补全
sortTemp=sortTemp.slice(0,sortTemp.length-1)//清空
isRepeat[temp]=true;
}
}
}
return result;
}
28.数组中出现次数超过一半的数字
function MoreThanHalfNum_Solution(numbers)
{
// write code here
var obj={};
var len = numbers.length;
numbers.map(function(num){
if(obj[num]){
obj[num]++
}else{
obj[num]=1;
}
})
for (var i in obj){
if(obj[i]>Math.floor(len/2)) return i
}
return 0;
}
29.最小的k个数
function GetLeastNumbers_Solution(input, k)
{
// write code here
if(input==null){
return null;
}
if(input.length<k){
return [];
}
input.sort(function(a,b){
return a>b;
})
var result = [];
for(var i=0;i<k;i++){
result.push(input[i]);
}
return result;
}
30.连续子数组的最大和
function FindGreatestSumOfSubArray(array)
{
// write code here
if (array.length === 0) return 0;
var max = array[0];
var temp = array[0];
for (var i = 1; i < array.length; i++) {
temp = temp > 0 ? temp + array[i] : array[i];
max = max > temp ? max : temp;
}
return max;
}
31.从1到n数字中1出现的次数
function NumberOf1Between1AndN_Solution(n)
{
// write code here
if(n<0){
return 0;
}
var count=0;
for(var i = 1;i<=n;i++){
var number = i;
while(number>0){
if(number%10==1){
count++;
}
number = Math.floor(number/10);
// console.log(number);
}
}
return count;
}
32.把数组排成最小的数
function PrintMinNumber(numbers)
{
// write code here
if (!numbers.length)
return "";
min=Number.POSITIVE_INFINITY;
return Sort(numbers, 0);
}
function Sort(numbers, index) {
for (var i = index, l = numbers.length; i < l; ++i) {
var temp = numbers[i];
numbers[i] = numbers[index];
numbers[index] = temp;
if (index != numbers.length - 1)
Sort(numbers, index + 1, min);
else {
var tempS = numbers.join("").toString();
if (min > tempS) {
min = tempS;
}
}
temp = numbers[i];
numbers[i] = numbers[index];
numbers[index] = temp;
}
return min;
}
33.“丑数”
function GetUglyNumber_Solution(index)
{
// write code here
var res = [],
multiply2 = 0,
multiply3 = 0,
multiply5 = 0,
nextIndex = 1
res[0] = 1
if(index <= 0)
return 0
while(nextIndex < index)
{
res[nextIndex] = min( res[multiply2] * 2, res[multiply3] * 3, res[multiply5] * 5 )
while( res[multiply2] * 2 <= res[nextIndex] )
{
++multiply2
}
while( res[multiply3] * 3 <= res[nextIndex] )
{
++multiply3
}
while( res[multiply5] * 5 <= res[nextIndex] )
{
++multiply5
}
++nextIndex
}
return res[--nextIndex]
}
function min(a,b,c)
{
var min
min = (a < b) ? a : b
min = (min < c) ? min : c
return min
}
34.第一个只出现一次的字符
function FirstNotRepeatingChar(str)
{
// write code here
if(!str){
return -1;
}
var flag = {};
var len = str.length;
for(var i = 0;i<len;i++){
if(flag[str[i]]){
if(flag[str[i]]>2){
continue;
}else{
flag[str[i]]++;
}
}else{
flag[str[i]] = 1;
}
}
for(var i = 0;i<len;i++){
if(flag[str[i]] == 1){
return i;
}
}
}
module.exports = {
FirstNotRepeatingChar : FirstNotRepeatingChar
};
35.数组中的逆序对
function InversePairs(data)
{
// write code here
if(!data || data.length < 2){
return 0;
}
var copy = data.concat(), count = 0;
count = MergeSort(data, copy, 0, data.length-1);
return count % 1000000007;
}
function MergeSort(data, copy, start, end){
if(end === start){
return 0;
}
var len = Math.floor((end - start) / 2);
var left = MergeSort(copy, data, start, start+len);
var right = MergeSort(copy, data, start+len+1, end);
var count = 0;
var p = start+len, q = end, copyIndex = end;
while(p >= start && q >= start+len+1){
if(data[p] > data[q]){
count += q - start - len;
copy[copyIndex--] = data[p--];
}else{
copy[copyIndex--] = data[q--];
}
}
while(p >= start){
copy[copyIndex--] = data[p--];
}
while(q >= (start+len+1)){
copy[copyIndex--] = data[q--];
}
return left + right + count;
}
module.exports = {
InversePairs : InversePairs
};
36.两个链表的第一个公共结点
function ListNode(x){
this.val = x;
this.next = null;
}
function FindFirstCommonNode(pHead1, pHead2)
{
// write code here
var arr1 = [],
arr2 = [],
p1 = pHead1,
p2 = pHead2,
index = -1;
while(p1){
arr1.push(p1.val);
p1 = p1.next;
}
while(p2){
arr2.push(p2.val);
p2 = p2.next;
}
for(var i = 0 ; i < arr1.length; i ++){
var arr = arr1.slice(i);
var str1 = arr.join("-");
var str2 = arr2.join("-");
if(str2.indexOf(str1) > -1){
index = i;
break;
}
}
if(index < 0){return null;}
var p = pHead1;
while(index > 0){
p = p.next;
index --;
}
return p;
}
module.exports = {
FindFirstCommonNode : FindFirstCommonNode
};
37.数字在排序数组中出现的次数
function GetNumberOfK(data, k)
{
// write code here
if (data == null) {
return 0;
}
var leftIndex = leftIndexOfKeyInSortedArray(data, k);
if (leftIndex == -1) {
return 0;
}
var rightIndex = rightIndexOfKeyInSortedArray(data, k);
return rightIndex - leftIndex + 1;
}
function leftIndexOfKeyInSortedArray(data, key) {
if (data == null) {
return -1;
}
var low = 0;
var high = data.length - 1;
var ret = -1;
while (low <= high) {
var mid = Math.floor((low + high) / 2);
if (data[mid] == key) {
ret = mid;
high = mid - 1;
} else if (data[mid] > key) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return ret;
}
function rightIndexOfKeyInSortedArray(data, key) {
if (data == null) {
return -1;
}
var low = 0;
var high =data.length - 1;
var ret = -1;
while (low <= high) {
var mid = Math.floor((low + high) / 2);
if (data[mid] == key) {
ret = mid;
low = mid + 1;
} else if (data[mid] > key) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return ret;
}
module.exports = {
GetNumberOfK : GetNumberOfK
};
38.二叉树的深度
function TreeDepth(pRoot)
{
// write code here
if(pRoot == null){
return 0;
}
var left = TreeDepth(pRoot.left)+1;
var right = TreeDepth(pRoot.right)+1;
return Math.max(left, right);
}
39.平衡二叉树
var isBalanced = true;
function isBalancedCore(pRoot) {
if (!pRoot) {
return 0;
}
var leftCount = 0;
var rightCount = 0;
if (pRoot.left) {
leftCount = isBalancedCore(pRoot.left);
}
if (pRoot.right) {
rightCount = isBalancedCore(pRoot.right);
}
if (Math.abs(leftCount - rightCount) > 1) {
isBalanced = false;
}
return leftCount > rightCount ? leftCount + 1 : rightCount + 1;
}
function IsBalanced_Solution(pRoot)
{
// write code here
if (!pRoot) {
return true;
}
isBalancedCore(pRoot);
var ret = isBalanced;
isBalanced = true;
return ret;
}
module.exports = {
IsBalanced_Solution : IsBalanced_Solution
};
40.数组中只出现一次的数字
function FindNumsAppearOnce(array)
{
// write code here
// return list, 比如[a,b],其中ab是出现一次的两个数字
var len = array.length,
num1,
num2,
resXOR = 0,
indexOf1
if( len < 2 )
return
for(var i=0; i<len; i++)
{
resXOR ^= array[i]
}
indexOf1 = find1( resXOR )
for(var j=0; j<len; j++)
{
if(IsBit1( array[j], indexOf1 ))
{
num1 ^= array[j]
} else {
num2 ^= array[j]
}
}
return [ num1, num2 ]
}
function find1(bit)
{
var index = 0
while((bit & 1) == 0)
{
bit = bit >> 1
index++
}
return index
}
function IsBit1(bit, index)
{
var num = bit >> index
return (num & 1)
}
module.exports = {
FindNumsAppearOnce : FindNumsAppearOnce
};
41.和为s的连续正整数序列
function FindContinuousSequence(sum)
{
// write code here
var low=1,high=2;
array=[];
while(high>low){
var cur=(high+low)*(high-low+1)/2;
if(cur<sum){
high++;
}
if(cur===sum){
var arr=[];
for(var i=low;i<=high;i++){
arr.push(i);
}
array.push(arr);
low++;
}
if(cur>sum){
low++;
}
}
return array;
}
module.exports = {
FindContinuousSequence : FindContinuousSequence
};
41.和为s的两个数字
function FindNumbersWithSum(array, sum)
{
// write code here
var len = array.length,
small = 0,
big = len - 1,
curSum = 0,
curMul,
mul = 9007199254740991,
res = []
if(len < 2)
return res
while(small < big)
{
curSum = array[small] + array[big]
if(curSum == sum)
{
curMul = array[small] * array[big]
if( curMul < mul )
{
mul = curMul
res.push( array[small], array[big] )
}
small ++
}
if(curSum < sum)
{
small++
} else if(curSum > sum)
{
big --
}
}
return res
}
module.exports = {
FindNumbersWithSum : FindNumbersWithSum
};
42.左旋转字符串
function LeftRotateString(str, n)
{
// write code here
if(!str||n<0) return "";
var strArr = str.split(""),
len = strArr.length;
if(n>len) return "";
var front = strArr.slice(0, n).reverse(),
behind = strArr.slice(n, len).reverse(),
newArr = front.concat(behind);
return newArr.reverse().join("");
}
module.exports = {
LeftRotateString : LeftRotateString
};
43.翻转单词顺序列
function ReverseSentence(str)
{
// write code here
if(!str||!str.trim()) return str;
var strArr = str.split(" "), //获取单词数组
len = strArr.length;
var start = 0,
end = len - 1,
temp;
while (start < end) {
temp = strArr[start];
strArr[start] = strArr[end];
strArr[end] = temp;
++start;
--end;
}
return strArr.join(" ").trim();
}
module.exports = {
ReverseSentence : ReverseSentence
};
44.扑克牌顺子
function IsContinuous(numbers)
{
// write code here
if (numbers.length==0) return false;
//先对数组进行排序
numbers.sort(function(a, b) {
return a - b;
});
var numberOfZero = 0, //0的个数
numberOfGap = 0; //缺的个数
var len = numbers.length;
for (var i = 0; i < len && (numbers[i] === 0); ++i) {
++numberOfZero;
}
var small = numberOfZero,
big = small + 1;
while (big < len) {
if (numbers[small] === numbers[big]) return false;
numberOfGap += numbers[big] - numbers[small] - 1;
small = big;
++big;
}
return numberOfGap <= numberOfZero ? true : false;
}
module.exports = {
IsContinuous : IsContinuous
};
45.孩子们的游戏
function LastRemaining_Solution(n, m)
{
// write code here
if(n === 0) {
return -1;
}
if(n === 1) {
return 0;
}
return (LastRemaining_Solution(n-1, m)+m) % n;
}
module.exports = {
LastRemaining_Solution : LastRemaining_Solution
};
46.求1+2+3+...+n
function Sum_Solution(n)
{
// write code here
// write code here
if(n==1){
return 1;
}else{
return n+Sum_Solution(n-1);
}
}
47.不用加减法乘除做加法
function Add(num1, num2)
{
// write code here
var sum = 0, tmp;
do{
sum = num1^num2;
tmp = num1&num2;
num1 = tmp << 1;
num2 = sum;
}while(tmp != 0);
return sum;
}
48.把字符串转化为整数
function StrToInt(str)
{
// write code here
if(/[a-zA-Z]/.test(str)){
return 0;
}
var reg = /([\+|\-]?\d+)/;
if(reg.test(str)){
str = str.replace(reg, "$1");
return str;
}else{
return 0;
}
}
module.exports = {
StrToInt : StrToInt
};
49.数组中重复的数字
function duplicate(numbers, duplication)
{
// write code here
//这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
//函数返回True/False
if(numbers==null) return false;
if(numbers.length==1) return false;
for(var i=0;i<numbers.length;i++){
if(numbers.indexOf(numbers[i]) != numbers.lastIndexOf(numbers[i])){
duplication[0]=numbers[i];
return true;
}
}
return false;
// write code here
//这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
//函数返回True/False
}
module.exports = {
duplicate : duplicate
};
50.构建乘积数组
function multiply(array)
{
// write code here
var B=[];
B[0]=1;
B[1]=array[0];
for(var i=2;i<array.length;i++){
B[i]=B[i-1]*array[i-1];
}
var sum=1;
for(var i=array.length-2;i>=0;i--){
sum=sum*array[i+1];
B[i]=B[i]*sum;
}
return B;
}
module.exports = {
multiply : multiply
};
51.正则表达式匹配
//s, pattern都是字符串
function match(s, pattern)
{
// write code here
var patt=new RegExp('^'+pattern+'$');
return patt.test(s);
}
module.exports = {
match : match
};
52.表示数值的字符串
//s字符串
function isNumeric(s)
{
// write code here
var reg = !isNaN(Number(s));
return reg
}
module.exports = {
isNumeric : isNumeric
};
53.字符流中第一个不重复的字符
//Init module if you need
function Init()
{
// write code here
global.result = [];
return global.result
}
//Insert one char from stringstream
function Insert(ch)
{
// write code here
if(result[ch]){
result[ch]++
} else {
result[ch] = 1;
}
}
//return the first appearence once char in current stringstream
function FirstAppearingOnce()
{
// write code here
for(var i in result){
if(result[i] === 1){
return i;
};
};
return '#';
}
module.exports = {
Init : Init,
Insert : Insert,
FirstAppearingOnce: FirstAppearingOnce
};
54.链表中环的入口结点
function EntryNodeOfLoop(pHead)
{
// write code here
var cur =pHead,obj={},lt;
while(cur!=null){
lt=cur.val;
if(!obj[lt]){
obj[lt]=1;
cur=cur.next;
}else{
return cur;
}
}
}
module.exports = {
EntryNodeOfLoop : EntryNodeOfLoop
};
55.删除链表中重复的结点
function deleteDuplication(pHead)
{
// write code here
if(pHead === null) return null;
if(pHead !== null && pHead.next === null) return pHead;
var first = {
val: -1,
next: pHead
}
cur = pHead,
prev = first;
first.next = pHead;
while(cur !== null && cur.next !== null){
if(cur.val === cur.next.val){
var val = cur.val;
while(cur !== null && cur.val === val){
cur = cur.next;
prev.next = cur;
};
} else {
prev = cur;
cur = cur.next;
};
};
return first.next;
}
module.exports = {
deleteDuplication : deleteDuplication
};
56.二叉树的下一个结点
function GetNext(pNode)
{
// write code here提示数组非法越界 是因为代码有中文状态下的
if(pNode==null){
return null;
}
//分两种情况:1 节点有孩子存在,则设置一个指针从该节点的右孩子出发,一直沿着指向左节点的指针 找到叶子结点即为下一个节点
if(pNode.right!=null){
var p=pNode.right;
while(p.left!=null){
p=p.left;
}
return p;
}
//2 该节点是父亲节点的左节点 没有右子树 则找第一个当前节点是父亲节点坐孩子的节点
while(pNode.next!=null){
if(pNode==pNode.next.left){//当前节点是父节点的第一个左节点并且该节点没有右子树
return pNode.next;
}
pNode=pNode.next;
}
}
module.exports = {
GetNext : GetNext
};
57.对称的二叉树
function isSymmetrical(pRoot)
{
// write code here
//对称二叉树 首先根节点以及其左右子树,左子树的左子树和右子树的右子树
//左子树的右子树和右子树的左子树相同即可 采用递归法
if(pRoot==null){
return true;
}
return comRoot(pRoot.left,pRoot.right);
}
function comRoot(left,right){
if(left==null&&right==null){
return true;
}
if(left!=null&&right!=null){
if(left.val==right.val){
return comRoot(left.left,right.right)&&comRoot(left.right,right.left);
}
}
}
module.exports = {
isSymmetrical : isSymmetrical
};
58.按之字型打印二叉树
function Print(pRoot)
{
var result=[];
// write code here
if(pRoot==null){
return result;
}
var queue=[];
var nextLevel=0;
queue.push(pRoot);
var toBePrinted=1;
var level=0;
var arr=[];
while(queue.length){
var temp=queue.shift();
toBePrinted--;
arr.push(temp.val);
if(temp.left){
queue.push(temp.left);
nextLevel++;
}
if(temp.right){
queue.push(temp.right);
nextLevel++;
}
if(toBePrinted==0){
toBePrinted=nextLevel;
nextLevel=0;
level++;
if(level%2==0){
arr.reverse();
}
result.push(arr);
arr = [];
}
}
return result;
}
59.把二叉树打印成多行
function Print(pRoot)
{
// write code here
var res=[]
if(!pRoot)return res
var q=[]
q.push(pRoot)
while(q.length!=0){
var l=0
var h=q.length
var arr=[]
while(l++<h){
var t=q.shift()
arr.push(t.val)
if(t.left)q.push(t.left)
if(t.right)q.push(t.right)
}
res.push(arr)
}
return res
}
60.序列化二叉树
function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
}
var arr = [];
function Serialize(pRoot)
{
// write code here
if(pRoot==null){
arr.push('a');
}else{
arr.push(pRoot.val);
Serialize(pRoot.left);
Serialize(pRoot.right);
}
}
function Deserialize(s)
{
// write code here
var node = null;
if(arr.length<1){
return null;
}
var number = arr.shift();
if(typeof number == 'number'){
node = new TreeNode(number);
node.left = Deserialize(arr);
node.right = Deserialize(arr);
}
return node;
}
61.二叉搜索树的第k个结点
function KthNode(pRoot, k)
{
// write code here
var arr=[];
if(pRoot===null||k<1){
return null;
}
function midInorder(root){
if(root.left!==null){
midInorder(root.left);
}
arr.push(root);
if(root.right!==null){
midInorder(root.right);
}
}
midInorder(pRoot);
return arr[k-1];
}
62.数据流中的中位数
var arr=[];
function Insert(num)
{
arr.push(num);
arr.sort();
}
function GetMedian(){
/*if(arr==null){
return 0;
}*/
var len=arr.length;
if(len==0){
return 0;
}
if(len%2==1){
return arr[Math.floor(len/2)];
}
if(len%2==0){
//var a=Math.floor(len/2);
// var b=Math.ceil(len/2);
//return (arr[a]+arr[b])/2;
return (arr[len/2]+arr[len/2-1])/2;
}
}
63.滑动窗口的最大值
function maxInWindows(num, size)
{
// write code here
var q=[];
var max=-1;
var v=[];
var i=0;
if(size>num.length||size<=0) return v;
while(size--){
q.push(num[i]);
if(num[i]>max) max=num[i];
i++;
}
v.push(max);
while(i<num.length){
var m=q.shift();
if(m==max){
max=getMax(q);
}
q.push(num[i]);
if(num[i]>max) max=num[i];
v.push(max);
i++;
}
return v;
}
function getMax(q){
var max=-1;
for(var i=0;i<q.length;i++){
if(q[i]>max){
max=q[i];
}
}
return max;
}
64.矩阵中的路径
function hasPathCore(matrix, rows, cols, row, col, path, pathIndex, visited) {
var hasPath = false;
if (row < rows && col < cols && row >= 0 && col >= 0 && visited[row][col] === false) {
if (matrix[row * cols + col] === path[pathIndex]) {
visited[row][col] = true;
if (pathIndex === path.length - 1) {
hasPath = true;
} else {
hasPath = hasPathCore(matrix, rows, cols, row - 1, col, path, pathIndex + 1, visited) ||
hasPathCore(matrix, rows, cols, row + 1, col, path, pathIndex + 1, visited) ||
hasPathCore(matrix, rows, cols, row, col - 1, path, pathIndex + 1, visited) ||
hasPathCore(matrix, rows, cols, row, col + 1, path, pathIndex + 1, visited);
if (!hasPath) {
visited[row][col] = false;
}
}
}
}
return hasPath;
}
function hasPath(matrix, rows, cols, path)
{
// write code here
if (path.length <= 0) {
return true;
}
var visited = [];
var temp = [];
var i, j;
for (i = 0; i < rows; i++) {
temp = [];
for (j = 0; j < cols; j++) {
temp.push(false);
}
visited.push(temp);
}
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
if (hasPathCore(matrix, rows, cols, i, j, path, 0, visited)) {
return true;
}
}
}
return false;
}
module.exports = {
hasPath : hasPath
};
65.机器人的运动范围
function movingCount(threshold, rows, cols)
{
// write code here
var count=0;
if(threshold<1||rows<1||cols<1){
return count;
}
var visited=[];
for(var i=0; i<rows; i++){
visited[i]=[];
for(var j=0; j<cols; j++){
visited[i][j]=false;
}
}
count = movingCountSum(threshold,0,0,rows,cols,visited);
return count;
}
function movingCountSum(threshold,m,n,rows,cols,visited){
var count = 0;
if(m>=0&&m<rows&&n>=0&&n<cols&&!visited[m][n]&&getSum(m,n)<=threshold){
visited[m][n]=true;
count = 1+movingCountSum(threshold,m,n-1,rows,cols,visited)+
movingCountSum(threshold,m,n+1,rows,cols,visited)+
movingCountSum(threshold,m-1,n,rows,cols,visited)+
movingCountSum(threshold,m+1,n,rows,cols,visited);
}
return count;
}
function getSum(m,n){
var str = [].concat(m,n).join('');
var sum=0;
for(var i=0; i<str.length; i++){
sum+=Number(str[i]);
}
return sum;
}
module.exports = {
movingCount : movingCount
};