LeetCode 转为 34 位二进制搜索
自从我开通算法博客以来,一些读者质疑博客中大公司面试问题的真实性。在之前的知乎评论中,我已经回复过并列出了一些依据。现在看来,完全没有必要了。这里声明一下,所有的算法题都是个人精心整理和审核的。这些算法题的选择是基于个人的判断和对一些代表高级算法学习的典型问题的理解。最后,我想再次声明,我开算法博客的初衷是为了帮助有需要的人。之前的一篇博客LeetCode进阶4-分而治之,也介绍了分而治之的方法。给定一个按升序排序的整数数组 nums,找到给定目标值的起始位置和结束位置。您的算法的运行时复杂度必须约为 O。
聊天
自从我开通算法博客以来,一些读者质疑博客中大公司面试问题的真实性。 在之前的知乎评论中,我已经回复过并列出了一些依据。 现在看来,完全没有必要了。 这里声明一下,所有的算法题都是个人精心整理和审核的。 有的是来自一些开源社区,有的是来自一些开发者的面试经历(面试经历),还有的是从一些技术网站获得的。 这些算法题的选择是基于个人的判断和对一些代表高级算法学习的典型问题的理解。 以后类似的问题我不会回复。 最后,我想再次声明,我开算法博客的初衷是为了帮助有需要的人。 如果您有任何技术问题,欢迎随时交流。 如果你是这样的人,请不要打扰~
概括
二分查找又称为半查找,是分而治之思想的典型应用,是一种高效的查找方法。 半查找要求线性表必须采用顺序存储结构,表中的元素必须按关键字按顺序排列。 之前的一篇博客LeetCode进阶4-分而治之,也介绍了分而治之的方法。 本文进一步介绍了经典算法的思想应用——二分查找。
34. 查找排序数组中元素的第一个和最后一个位置(中)
给定一个按升序排序的整数数组 nums,找到给定目标值的起始位置和结束位置。
您的算法的运行时复杂度必须约为 O(log n)。
如果在数组中未找到目标,则返回 [-1, -1]。
示例1:
输入:nums = [5,7,7,8,8,10],目标 = 8
输出:[3,4]
示例2:
输入:nums = [5,7,7,8,8,10],目标 = 6
输出:[-1,-1]
34. 查找排序数组中元素的第一个和最后一个位置(中)
给定一个按升序排列的整数数组 nums 和一个目标值 target。 查找给定目标值在数组中的开始和结束位置。
你的算法的时间复杂度必须是O(log n)级别。
如果数组中不存在目标值,则返回[-1, -1]。
示例1:
输入:nums = [5,7,7,8,8,10],目标 = 8
输出:[3,4]
示例2:
输入:nums = [5,7,7,8,8,10],目标 = 6
输出:[-1,-1]
想法分析
按照正常的二分查找思路,循环查找与目标数匹配的下标,继续将右指针变小,找到第一个目标数。 使用新的循环从左到右从找到的第一个目标编号的索引开始搜索,直到找到最后一个目标编号。 (具体搜索思路见伪代码)
伪代码
1、相关声明 1.1、声明搜索用的左右指针,初始左指针下标0,右指针下标数组末位nums.length-1; 1.2、获取数组中间下标mid = (l + r) / 2; 1.3、声明创建结果数组,初始化赋值-1; 2、循环二分查找,直到左指针大于右指针查找结束 2.1、若中间位置数字小于目标数字,说明目标数字在mid右边,将左指针l右移赋值为mid+1; 2.2、若中间位置数字大于目标数字,说明目标数字在mid左边,将右指针r左移赋值为mid-1; 2.3、若中间位置数字等于目标数字: 2.3.1、将mid作为第一次出现位置存入数组; 2.3.2、右指针r左移赋值为mid-1,继续查找相等的数字直到找到第一次出现的位置; 2.4、更新mid; 3、从第一次出现的位置开始,循环往右查找最后一次出现的位置: 3.1、声明pr指针初始赋值为第一次出现位置下标; 3.2、当二分查找已找到目标数字时 3.2.1、循环直到数组越界或者数组当前元素不等于目标元素时结束: 3.2.1.1、更新最后一次出现位置下标; 3.2.1.2、更新之后往右移动指针; 4、最终返回已存储位置的结果数组;
编码实践
public int[] searchRange(int[] nums, int target) { int l = 0, r = nums.length - 1; int mid = (l + r) / 2; int res[] = { -1, -1 }; while (l <= r) { if (nums[mid] < target) { l = mid + 1; } else if (nums[mid] > target) { r = mid - 1; } else { res[0] = mid; r = mid - 1; } mid = (l + r) / 2; } int pr = res[0]; if (pr != -1) { while (pr <= nums.length - 1 && target == nums[pr]) { res[1] = pr++; } } return res; }
扩展 扩展
这个问题其实之前在头条笔试题中就出现过
有序数组中的二分搜索返回找到该元素最后一次出现的位置,如果不存在则返回 -1。
如果你有兴趣,可以根据上面的思路思考一下。 下面是解决方案的参考代码:
public static int searchRange(int[] nums, int target) { int l = 0, r = nums.length - 1; int mid = (l + r) / 2; int res = -1; while (l <= r) { if (nums[mid] < target) { l = mid + 1; } else if (nums[mid] > target) { r = mid - 1; } else { res = mid; l = mid + 1; } mid = (l + r) / 2; } return res; }
本书继续上面。
三国演义11:血衣14:人口系统介绍sire2.01d修改器使用详解
本篇我们就来说说如何使用sire2.01d来DIY各种特技。
添加和修改特效
例如,在第一张图所在的“特效”栏中,双击任意一个你想要修改的特技,就会进入如上图的界面。
该界面中,除特技编号不可修改外,其他位置均可修改。
包括“特技名称”、“特技类别”、“特技等级”、“特技描述”,关键是下面两项“特技效果组合”和“匹配军事单位”。
说到这里,就不得不说说“效果”这个大项了。
因为在新版本的《sire》中,RK大师已经将所有特效的效果进行了统一,或者将各个特效细分为基本效果。
比如我们来对比一下“神将”和“勇将”两个非常相似的特技效果。
它们有4个类似的小效果,分别是“枪、戟、弩、高武器和炸药的骑兵战术”,编号为35、36、37和38。
也就是说,如果四大主战兵种的力量高于对方的战术,就会发生暴击。
不同的是,“神将”的“普通攻击高武器爆炸”编号为32,而“勇敢将军”的“工水战高武器爆炸”编号为39和40。
而且,在《神将》界面中,底部的“适合兵种”栏目中,“武器”和“海军”并没有勾选。 这意味着“神将”的效果无法影响“武器”和“海军”。 陆军”生效。并且“勇将”全部勾选,也就是说“勇将”效果适用于所有兵种。
需要注意的是,39号的“工业战和高爆炸药”只针对部队,不包括建筑物。
因为,构建暴击,还有另外两个分支:第34号“设施不灭爆炸”和第45号“工业战必爆”。
总的来说,根据上面的战术效果分解,可以清楚的看出这个战术的实际效果。 而不是像一开始那样,只是通过经验去一点一点去尝试。
因此,我们可以DIY一个我们喜欢的特技,或者根据我们想要的东西定制。
添加新的实际上与修改它类似。
只需右键单击“特效”项下的任意位置,或者双击作者保留的位置,就会打开一个类似于上面的空白界面。
然后你就可以想玩什么就玩什么。 您可以参考“效果”项的功能介绍。
比如我随机做了一个骑兵特技。 其实我觉得有点浪费。 数字30、33和315的三种效果可能根本没有体现出来。 应该是一秒钟的时间。
编辑完成后,该界面右上角有三个选项。 红色标记的位置。
第 1 个是“另存为”,它允许您导出编辑效果。
第2个是“导入”,这意味着读取您导出的编辑文件。
第三个是“恢复默认值”。
就是这样。
不不不,“效果”选项也是可以修改的。
该界面中,除“名称”和“描述”不可修改外,后续的各种“参数”都可以直接修改数值或在下拉菜单中选择。
比如你觉得暴击伤害加20%还不够,那就改成30%,就没问题了。 当然,各种数值也有上限和下限。 例如,暴击伤害介于 0-100% 之间。 它也不会让你做得太过分。
在该页面的右上角,有与“特技”页面相同的三个选项。
如果您更改过,请记得保存。 请记住在每次进入游戏之前加载您的配置,然后加载sire。
结论
Sire可以在原来的311上使用,但是对于新添加的特效,只能通过武将来一一调整,否则根本不会出现在游戏中。
sire最大的优势不是玩mod,而是你可以制作一台你喜欢的311。
一项特技可以产生 12 种效果。 我觉得这样的噱头已经太厉害了。
我曾经使用过PKME修改器并将其调整为完整的特技。 2分钟后我就停止玩了。 真的很无聊。
为了可玩,它必须很强,但又不能强得离谱。
这就是本文的内容。
我把自己挂在钩子上,一百年都不会改变。 感谢您的支持。