zoukankan      html  css  js  c++  java
  • 面试常见算法

    参考:奇舞周刊

    位运算

    汉明距离 两个等长的字符串对应位置上的字符不同的个数

    汉明重量 他是一个特殊的汉明距离,指一个字符串中非零字符的个数

    计算汉明重量

    function hanmingWeight(n) {
        let num = 0;
        while(n !== 0) {
            n &= (n-1);
            num++;
        }
        return num;
    }
    

    判断奇偶数

    // 0001 0010 0011 0100 0101 0110 0111 1000
    // 1    2    3    4    5    6    7    8
    // 0001
    function isOdd(n) {
        return n & 1 === 1;
    }
    

    二分查找

    将原本是线性时间提升到了对数时间范围, 使用前提,必须在有序集合中查找

    不用递归

    function binarySearch(nums, target) {
        let high = nums.length - 1;
        let low = 0;
        while(low < high) {
            // parseInt向下取整
            let mid = parseInt((low + high) / 2);
            if (nums[mid] === target) {
                return mid;
            }
            if (nums[mid] > target) {
                // 不包括mid
                high = mid - 1;
            }
            if (nums[mid] < target) {
                // 不包括mid
                low = mid + 1;
            }
        }
    }
    

    递归

    function binarySearch2(nums, target) {
        let low = 0;
        let high = nums.length - 1;
    
        const binaryWalk = (nums, low, high, target) => {
            if (low > high) return -1;
            let mid = parseInt((low + high) / 2);
            if (nums[mid] === target) return mid;
            if (nums[mid] > target) binaryWalk(nums, low, mid - 1, target);
            if (nums[mid] < target) binaryWalk(nums, mid + 1, high, target);
        }
        return binaryWalk(nums, low, high, target);
    }
    

    常见排序

    快速排序

    冒泡排序的改进版

    任意选取一个元素作为基准(一般选取第一个元素),将待排序元素进行分区,比基准元素大的放右边,小的放左边

    function quickSort(arr) {
        const len = arr.length;
        if(len <= 1) return arr;
        let left = [];
        let right = [];
        let pivot = arr[0];
        for (let i = 1;i < len; i++) {
            if (arr[i] >= pivot) {
                right.push(arr[i]);
            } else {
                left.push(arr[i]);
            }
        }
        return [...quickSort(left), ...quickSort[right]];
    }
    

    冒泡排序

    比较相邻的元素,如果第一个比第二个大,就交换他们, 完成该步骤后,最后一个元素是数组中最大的数

    针对所有元素重复上述步骤,除了最后一个

    持续对越来越少的元素重复上述步骤,直到没有数字可以比较

    function bubbleSort(arr) {
        let i = arr.length - 1;
        while(i > 0) {
            for(let j=0; j < i; j++) {
                if(arr[j] > arr[j + 1])  {
                    [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
                }
            }
            i--;
        }
    
        return arr;
    }
    

    二叉树

    有限个节点的集合

    先序遍历

    根节点排最先,然后同级先左后右

    递归实现

    function preOrderTraverse(root) {
        if (root) {
            console.log(root);
            preOrderTraverse(root.left);
            preOrderTraverse(root.right);
        }
    }
    

    非递归实现

    function preOrderTraverse1(root) {
        let stack = [];
    
        if (root) {
            stack.push(root);
        }
    
        while(stack.length) {
            // 删除并返回数组的最后一个元素
            let temp = stack.pop();// 先进后出
            console.log(temp);
    
            if(temp.right) stack.push(temp.right);
    
            if(temp.left) stack.push(temp.left);
        }
    }
    

    中序遍历

    先左后根最后右

    递归实现

    function midOrderTraverse(root) {
        if(root) {
            midOrderTraverse(root.left);
            console.log(root);
            midOrderTraverse(root.right);
        }
    }
    

    非递归实现

    function midOrderTraverse1(root) {
        let stack = [];
        while(true) {
            while(root) {
                stack.push(root);
                root = root.left;
            }
    
            if(!stack.length) break;
    
            let temp = stack.pop();
            console.log(temp);
            root = temp.right;
        }
    }
    

    后序遍历

    先左后右最后根

    递归实现

    function postOrderTraverse(root) {
        if (root) {
            postOrderTraverse(root.left);
            postOrderTraverse(root.right);
            console.log(root);
        }
    }
    

    非递归实现

    function postOrderTraverse1(root) {
        let stack = [];
        let rest = [];
        if(root)stack.push(root);
        while(stack.length) {
          let temp = stack.pop();
          rest.push(temp);
          if(temp.left) stack.push(temp.left);
          if(temp.right) stack.push(temp.right);
        }
        return rest.reverse();
      }
    

    层叠遍历

    从上到下一层一层遍历

    function levelTraverse(root) {
        if(!root) return;
        let stack = [];
        stack.push(root);
        while(stack.length) {
            // 删除数组中的第一个元素并返回
            let temp = stack.shift();// 先进先出
            console.log(temp);
            if(temp.left) stack.push(temp.left);
            if(temp.right) stack.push(temp.right);
        }
    }
    
  • 相关阅读:
    NanoProfiler
    NanoProfiler
    Open Source Cassandra Gitbook for Developer
    Android Fragment使用(四) Toolbar使用及Fragment中的Toolbar处理
    Android Fragment使用(三) Activity, Fragment, WebView的状态保存和恢复
    Android Fragment使用(二) 嵌套Fragments (Nested Fragments) 的使用及常见错误
    Android Fragment使用(一) 基础篇 温故知新
    Set up Github Pages with Hexo, migrating from Jekyll
    EventBus源码解析 源码阅读记录
    Android M Permission 运行时权限 学习笔记
  • 原文地址:https://www.cnblogs.com/goOtter/p/11102401.html
Copyright © 2011-2022 走看看