算法基础之简单线性算法

本文包括简单的线性算法和一些数值计算,还会在以后的学习中继续更新

rgb 和 16进制互相转换

function rgb2hex(r,g,b){
  return "#" + ((r<<16)+(g<<8)+b).toString(16);
}
function hex2rgb(str){
  var arr = str.match(/[0-9a-f]{2}/ig);
  return {
    r: parseInt(arr[0], 16),
    g: parseInt(arr[1], 16),
    b: parseInt(arr[2], 16)
  };
}

找出整型数组中乘积最大的三个数

var original_array = [-10, -7, -29, -4, -1, -10, -70];
var result = findMPTN(original_array);
console.log(result);

function findMPTN(arr){    //findMaxiumProductorOfThreeNumbers
  var len = arr.length;
  sorted_arr = arr.sort(function(a,b){return a-b;});
  var pro1 = 1, pro2 = sorted_arr[len - 1];
  for(var i = 1; i <= 3; i++){
    pro1 *= sorted_arr[len - i];
  }
  pro2 *= sorted_arr[0];
  pro2 *= sorted_arr[1];

  return pro1 > pro2 ?
  [sorted_arr[len - 3], sorted_arr[len - 2], sorted_arr[len - 1]] :
  [sorted_arr[0], sorted_arr[1], sorted_arr[len - 1]];
}

判断大括号是否闭合

var expression = "{{}}{}{}"
var expressionFalse = "{}{{}";

console.log(isBalanced(expression)); // true
console.log(isBalanced(expressionFalse)); // false
console.log(isBalanced("")); // true

function isBalanced(exp){
  var stack = [];
  var arr = exp.split("");
  var len = arr.length, cur;
  while(cur = arr.shift()){
    if(cur === "{") stack.push(cur);
    if(cur === "}") stack.pop();
  }
  if(stack.length !== 0) return false;
  return true;
}

使用两个栈实现入队与出队

Array.prototype.enqueue = function(item){
  return this.push(item);
};
Array.prototype.dequeue = function(){
  var tempStack = [];
  var cur, temp;
  while(cur = this.pop()){
    tempStack.push(cur);
  }
  temp = tempStack.pop();
  while(cur = tempStack.pop()){
    this.push(cur);
  }
  return temp;
};

寻找连续数组中的缺失的多个数

var array = [2, 5, -1, 9, -6, 3, 7];
var result = findLost(array);
console.log(result);

function findLost(arr){
  if(arr.length <= 1) return null;
  var sortedArr = arr.sort(function(a,b){return a-b;});
  var i = sortedArr.shift();
  var cur = sortedArr.shift();
  var result = [];
  do{
    i++;
    if(cur === i) cur = sortedArr.shift();
    else result.push(i);
  }while(cur);
  return result;
}

数组中元素最大差值计算

给定某无序数组,求取任意两个元素之间的最大差值,注意,这里要求差值计算中较小的元素下标必须小于较大元素的下标。

var array = [7, 8, 4, 9, 9, 15, 3, 1, 10];
var result = findLargestDifference(array);
console.log(result);
function findLargestDifference(arr){
  var min = arr[0];
  var diff = 0;
  for(var i = 1, len = arr.length; i < len; i++){
    if(arr[i] < min){
      min = arr[i];
      continue;
    }
    if(arr[i] - min > diff){
      diff = arr[i] - min;
    }
  }
  return diff;
}

数组中元素乘积

给定某无序数组,要求返回新数组 output ,其中 output[i] 为原数组中除了下标为 i 的元素之外的元素乘积,要求以 O(n) 复杂度实现:

var firstArray = [2, 2, 4, 1];
var secondArray = [0, 0, 0, 2];
var thirdArray = [-2, -2, -3, 2];

console.log(productExceptSelf(firstArray)); // [8, 8, 4, 16]
console.log(productExceptSelf(secondArray)); // [0, 0, 0, 0]
console.log(productExceptSelf(thirdArray)); // [12, 12, 8, -12]

function productExceptSelf(arr){
  var result = [];
  var pro = 1;
  var len = arr.length;
  for(var i = 0; i < len; i++){
    result.push(pro);
    pro *= arr[i];
  }
  pro = 1;
  for(i = len - 1; i >= 0; i--){
    result[i] *= pro;
    pro *= arr[i];
  }
  return result;
}

数组扁平化

var arr = [1,2,[1,3,[2,[2,3,3],[2,5]]],[6,3]];

//传统方式
function flat(arr,result=[]){
  if(arr.constructor !== Array) return [arr];
  var length = arr.length;
  arr.forEach(function(item){
    if(item.constructor !== Array) result.push(item);
    else result = flat(item, result);
  });
  return result;
}
var flatted = flat(arr);
console.log(flatted);          //[1, 2, 1, 3, 2, 2, 3, 3, 2, 5, 6, 3]

//优雅方式
var arr=[1,3,4,5,[6,[0,1,5],9],[2,5,[1,5]],[5]];
var flatter = arr => arr.reduce((a, b) => a.concat(Array.isArray(b) ? flatter(b) : b), []);
console.log(flatter(arr));        //[1, 2, 1, 3, 2, 2, 3, 3, 2, 5, 6, 3]

//另一个方法,简单但有副作用:把数组内的值全部转换成了字符串类型
var flatten = a => a.join().split(',');
console.log(flatten(arr));     //["1", "2", "1", "3", "2", "2", "3", "3", "2", "5", "6", "3"]

查找字符串中出现次数最多的字符及数量

"ababccdeaeajxac".split('').sort().join('').match(/(\w)\1*/g).reduce(function(a,b){ return a.length > b.length ? a : {char: b[0], length: b.length};}, {char: '', length: 0});       //{char: "a", length: 5}

字符串查找

String.prototype.indexOf = String.prototype.indexOf || function(str){
  if(str.length > this.length) return -1;
  var len = 0;
  var _this = this.split(''), str = str.split('');
  var lenA = str.length, this_len = this.length;
  var temp;
  for(var i = 0, j = 0; j < lenA; i = 0, j = temp + 1, len = 0){
    debugger;
    while(str[i] !== _this[j] && j < this_len){
      j++;
    }
    temp = j;
    while(str[i] === _this[j] && j < this_len){
      len++;
      i++;
      j++;
    }
    if(len === lenA) return temp;
  }
  return -1;
}

字符串查找(KMP 算法)

String.prototype.indexOf = String.prototype.indexOf || function(str){
  var next = [];
  var n = this.length;
  var m = str.length;
  calcNext(str,next);
  for (var i = 0,q = 0; i < n; ++i){
      while(q > 0 && str[q] != this[i])
          q = next[q-1];
      if (str[q] === this[i]){
          q++;
      }
      if (q === m){
          return i - m + 1;
      }
  }
  return -1;


  function calcNext(str){
    var m = str.length;
    next[0] = 0;
    for(var q = 1, k = 0; q < m; ++q){
        while(k > 0 && str[q] != str[k])
            k = next[k-1];
        if (str[q] == str[k]){
            k++;
        }
        next[q] = k;
    }
  }
}

查看链表是否有环

function hasCircle(head){   //传入链表头
  var pos1 = head;
  var pos2 = head;
  while(pos2){
    pos1 = pos1.next;
    pos2 = pos2.next !== null ? pos2.next.next : null;
    if(pos1 === pos2) return true;
  }
  return false;
}

求一个数二进制中 1 的个数

function numberOf1(n){
    if(n < 0){
        n = n >>> 0;
    }
    var arr = n.toString(2).split('');
    return arr.reduce(function(a,b){
        return b === "1" ? a + 1 : a;
    },0);
}

翻转链表

/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function reverseList(pHead){
    var newHead, temp;
    if(!pHead){
        return null;
    }
    if(pHead.next === null){
        return pHead;
    } else {
        newHead = ReverseList(pHead.next);
    }
    temp = pHead.next;
    temp.next = pHead;
    pHead.next = null;
    temp = null;
    return newHead;
}

判断是否栈序输出

例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。

function isPopOrder(pushV, popV){
    if(!pushV.length || !popV.length){
        return false;
    }
    var temp = [];
    var popIndex = 0;
    var len = pushV.length;
    for(var i = 0; i < len; i++){
        temp.push(pushV[i]);
        while(temp.length && temp[temp.length - 1] === popV[popIndex]){
            temp.pop();
            popIndex++;
        }
    }
    return temp.length === 0;
}

获取字符串中字符的全排列(无重复)

function permutation(str){
    if(!str || str.length === 0){
        return [];
    }
    var result = [];
    var arr = str.split('');
    var temp = '';
    ordering(arr);
    result = result.filter(function(item, index){  //去重
      return result.indexOf(item) === index;
    });
    return result;

    function ordering(tempArr){
        if(tempArr.length === 0){
            result.push(temp);
            return;
        }
        for(var i = 0; i < tempArr.length; i++){
            temp += tempArr[i];
            insideArr = tempArr.concat();
            insideArr.splice(i,1);
            ordering(insideArr);
            temp = temp.substring(0, temp.length - 1);   //回溯
        }
    }
}

查找有环链表的入环节点

/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function EntryNodeOfLoop(pHead){
    if(!pHead){
        return null;
    }
    var meeting = meetingNode(pHead);
    if(!meeting){
        return null;
    }
    var nodeLoop = 1;
    var node1 = meeting;
    while(node1.next != meeting){
        node1 = node1.next;
        nodeLoop++;
    }
    node1 = pHead;
    for(var i = 0; i < nodeLoop; i++){
        node1 = node1.next;
    }
    var node2 = pHead;
    while(node1 != node2){
        node1 = node1.next;
        node2 = node2.next;
    }
    return node1;

    function meetingNode(node){
        if(!node || !node.next){
            return null;
        }
        var slow = node.next;
        var fast = slow.next;

        while(fast && slow){
            if(fast === slow){
                return fast;
            }
            slow = slow.next;
            fast = fast.next;
            if(fast){
                fast = fast.next;
            }
        }
        return null;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • 本文内容取自于小甲鱼的数据结构与算法。http://www.jianshu.com/p/230e6fde9c75 ...
    阿阿阿阿毛阅读 2,867评论 0 7
  • 大学的时候不好好学习,老师在讲台上讲课,自己在以为老师看不到的座位看小说,现在用到了老师讲的知识,只能自己看书查资...
    和珏猫阅读 1,434评论 1 3
  • 1.把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不...
    曲终人散Li阅读 3,292评论 0 19
  • 第一章 绪论 什么是数据结构? 数据结构的定义:数据结构是相互之间存在一种或多种特定关系的数据元素的集合。 第二章...
    SeanCheney阅读 5,735评论 0 19
  • 从海文颖的《接纳力》一书中,听到这句话,事错了,人没错。我仔细品味这句话。 我一定是曾被深深否认,事错了,人就错了...
    Lisa_001阅读 355评论 0 0