惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
D
Docker
Last Week in AI
Last Week in AI
WordPress大学
WordPress大学
月光博客
月光博客
小众软件
小众软件
量子位
V
Visual Studio Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Tailwind CSS Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
罗磊的独立博客
博客园 - 叶小钗
美团技术团队
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 三生石上(FineUI控件)
博客园 - 聂微东
博客园 - 司徒正美
Microsoft Azure Blog
Microsoft Azure Blog
博客园 - Franky
Hugging Face - Blog
Hugging Face - Blog
GbyAI
GbyAI
C
Check Point Blog

博客园 - 北山秋叶

macos 上的 zsh 启动问题记录 Keychron Max 键盘改键指南 Github 命令在 命令行 中访问特别慢的解决方法 ai 随想 影响记忆 monorepo(多包)管理中, 引入的 css 文件丢失的问题 (或者说package.json中的 sideEffects 的探索) 浏览器插件 Obsidian web 与 Obsidian 插件 local rest api 结合配置过程记录 package.json中的版本号 mac 下检测网络状态的命令 git clone 需要用户名密码的一个小问题 怎么才能写一个好代码 yeoman编写自己的脚手架 await和promise结合使用的问题 ngix反向代理-之反向 redux和flux究竟有什么不同, 说点自己的理解 npm发包记录 由一个聚焦-focus-事件异常跟踪引起的总结 git查看分支的几个方法 test-your-mind-快速测试自己的代码 给Promise在外部增加断点 js中调试技巧-打印日志信息
有趣的二分
北山秋叶 · 2020-07-18 · via 博客园 - 北山秋叶

有趣的算法

对算法一直很陌生, 以后也会很陌生, 因为我是程序员,而不是数学家或者算法工程师
可这阻止不了算法的有趣.

先有了 快慢指针,让人眼前一亮, 而后这里的二分方法又让人 一个激动

二分的方法很简单, 上来就是去找你的 一半 去, 快速定位.

整理的复杂度也会跟 快速排序等方法有得一拼.

二分的关键, 是找到中间 的, 然后对中间的进行目标比较, 然后继续中间划分

这个获取中间的场景随着头尾的变动, 所以也是变动的. 我们要跟随着使用的场景去修改头尾

比较经典的场景就是去寻找一个数的插入位置. 这里有一个数字, 这里有一个数字, 我需要快速的找到这个数字应该插入的位置

//这个数组是假定已经排好顺序的, 这样这个二分才有意义
//定义好左右位置
//const target = 3.5
const arr = [1,2,3,4,5]

let l = arr.length;
let i = 0, // 最左侧的位置
    j = l - 1; //最右侧的位置
let mid = i + Math.floor((j-i)/2) // 或者可以使用位移 (j-i)>>1

let ret = l; //暂定我们要返回的就是最后一个点

//直接选择中间的位置进行比较,

arr[mid] > target
//如果中间的位置的数值比目标大, 那么数值肯定在中间以左, 我们需要修改右侧的位置(相对的mid也会变动)
j = mid - 1;

//如果相等, 那么正好, 我们要的目标就是这个地方
ret = mid;

//同理, 如果中间的位置小, 那么数字肯定在中间以右, 我们需要修改左侧的位置
i = mid + 1

//step2:
//因为正常情况下, 我们认为我们的元素是从小到大金星排列的, 所以正常的时候, 插入位置在右侧(>=)
//所以上边的判断可以合并

arr[mid] >= target
ret = mid
j = mid -1

//每次修改后, 我们需要重新计算 `mid`, 所以我们将方法进行整理后 ,如下

//左侧索引小于右侧, i = j, 也可以, 代表我们的遍历还是有元素的
while (i <= j) {
    let mid = i + Math.floor((j-i)/2);
    if (arr[mid] >= target) {
        ret = mid;
        j = mid - 1;
    }
    else {
        i = mid + 1
    }
}


//step3: 我们整理成完整的方法

function findPosition(arr, target) {
    let l = arr.length;
    let i = 0, // 最左侧的位置
    j = l - 1; //最右侧的位置
    let ret = l;
    while (i <= j) {
        let mid = i + Math.floor((j-i)/2);//可以使用位移的方法, >>
        let mid = i + (j-i>>1); //注意运算符优先级 位移操作的优先级是小于 + - 的
        if (arr[mid] >= target) {
            ret = mid;
            j = mid - 1;
        }
        else {
            i = mid + 1
        }
    }

    return ret;

}