当前位置:首页 > 科技  > 知识百科

调整数组元素顺序,你了解几分?

来源: 责编: 时间:2023-08-07 16:30:11 350观看
导读 前言有一个整数数组,我们想按照特定规则对数组中的元素进行排序,比如:数组中的所有奇数位于数组的前半部分。实现思路我们通过一个实例来分析下:假设有这样一个数组:[2, 4, 5, 6,

前言zrY28资讯网——每日最新资讯28at.com

有一个整数数组,我们想按照特定规则对数组中的元素进行排序,比如:数组中的所有奇数位于数组的前半部分。zrY28资讯网——每日最新资讯28at.com

实现思路zrY28资讯网——每日最新资讯28at.com

我们通过一个实例来分析下:假设有这样一个数组:[2, 4, 5, 6, 7, 8, 9, 11],将奇数移动到最前面后,就是:[11, 9, 5, 7, 6, 8, 4, 2]。zrY28资讯网——每日最新资讯28at.com

通过观察后,我们发现在扫描这个数组的时候,如果发现有偶数出现在奇数的前面, 就交换他们的顺序,交换之后就符合要求了。zrY28资讯网——每日最新资讯28at.com

因此,我们可以维护两个指针:zrY28资讯网——每日最新资讯28at.com

第一个指针初始化时指向数组的第一个数字,它只向后移动;第二个指针初始化时指向数组的最后一个数字,它只向前移动;zrY28资讯网——每日最新资讯28at.com

在两个指针相遇之前,第一个指针总是位于第二个指针的前面。如果第一个指针指向的数字是偶数,并且第二个指针指向的数字是奇数,则交换这两个数字。zrY28资讯网——每日最新资讯28at.com

接下来,我们来通过图来描述下上述例子交换指针的过程,如下所示:zrY28资讯网——每日最新资讯28at.com

第一个指针永远指向偶数,如果不为偶数就向后移动;第二个指针永远指向奇数,如果不为奇数就向前移动;当两个指针各自指向的数都符合条件时,就交换两个元素的位置;交换完成后,重复上述步骤,直至两个指针相遇或者第一个指针位于第二个指针之后则代表问题已得到解决。zrY28资讯网——每日最新资讯28at.com

zrY28资讯网——每日最新资讯28at.com

实现代码zrY28资讯网——每日最新资讯28at.com

有了思路之后,我们来看下实现代码,如下所示:zrY28资讯网——每日最新资讯28at.com

export class AdjustArrayOrder {zrY28资讯网——每日最新资讯28at.com
// 指向数组元素的两个指针:一个指向数组头部、一个指向数组尾部zrY28资讯网——每日最新资讯28at.com
private begin = 0;zrY28资讯网——每日最新资讯28at.com
private end = 0;zrY28资讯网——每日最新资讯28at.com
zrY28资讯网——每日最新资讯28at.com
// 调整数组中奇数与偶数元素的位置:奇数位于偶数前面zrY28资讯网——每日最新资讯28at.com
reorderOddEven(arr: Array): void {zrY28资讯网——每日最新资讯28at.com
this.end = arr.length - 1;zrY28资讯网——每日最新资讯28at.com
while (this.begin < this.end) {zrY28资讯网——每日最新资讯28at.com
// 向后移动begin(转成二进制跟1做与运算,运算结果为0就表示为偶数),直至其指向偶数zrY28资讯网——每日最新资讯28at.com
while (this.begin < this.end && (arr[this.begin] & 0x1) !== 0) {zrY28资讯网——每日最新资讯28at.com
this.begin++;zrY28资讯网——每日最新资讯28at.com
}zrY28资讯网——每日最新资讯28at.com
zrY28资讯网——每日最新资讯28at.com
// 向前移动end(转成二进制跟1做与运算,运算结果为1就表示为奇数),直至其指向奇数zrY28资讯网——每日最新资讯28at.com
while (this.begin < this.end && (arr[this.end] & 0x1) === 0) {zrY28资讯网——每日最新资讯28at.com
this.end--;zrY28资讯网——每日最新资讯28at.com
}zrY28资讯网——每日最新资讯28at.com
zrY28资讯网——每日最新资讯28at.com
// begin指向了偶数,end指向了奇数zrY28资讯网——每日最新资讯28at.com
if (this.begin < this.end) {zrY28资讯网——每日最新资讯28at.com
// 交换两个元素的顺序zrY28资讯网——每日最新资讯28at.com
[arr[this.begin], arr[this.end]] = [arr[this.end], arr[this.begin]];zrY28资讯网——每日最新资讯28at.com
}zrY28资讯网——每日最新资讯28at.com
}zrY28资讯网——每日最新资讯28at.com
// 重置指针位置zrY28资讯网——每日最新资讯28at.com
this.begin = 0;zrY28资讯网——每日最新资讯28at.com
this.end = 0;zrY28资讯网——每日最新资讯28at.com
}zrY28资讯网——每日最新资讯28at.com
}代码的可扩展zrY28资讯网——每日最新资讯28at.com

性如果数组中的元素不按照奇前偶后排列,我们需要将其按照大小进行划分,所有负数都排在非负数的前面,应该怎么做?zrY28资讯网——每日最新资讯28at.com

聪明的开发者可能已经想到了方案:双指针的思路还是不变,我们只需修改内层while循环的的判断条件即可。zrY28资讯网——每日最新资讯28at.com

这样回答没有问题,确实解决了这个问题,那么如果再改改题目,我们需要把数组中的元素分为两部分,能被3整除的数都在不能被3整除的数前面,应该怎么做?zrY28资讯网——每日最新资讯28at.com

经过思考后,我们发现这个问题无论再怎么改变都有一个共同的部分:双指针的逻辑永远不会变。变化的只是判断条件,那么我们就可以把变化的部分提取成函数,当作参数让调用者传进来,这样就完美的解决了这个问题,也正是我们所提及的代码的可扩展性。zrY28资讯网——每日最新资讯28at.com

最后,我们来看下实现代码,如下所示:zrY28资讯网——每日最新资讯28at.com

// 元素排序zrY28资讯网——每日最新资讯28at.com
reorder(arr: Array, checkFun: (checkVal: number) => boolean): void {zrY28资讯网——每日最新资讯28at.com
this.end = arr.length - 1;zrY28资讯网——每日最新资讯28at.com
while (this.begin < this.end) {zrY28资讯网——每日最新资讯28at.com
// 向后移动beginzrY28资讯网——每日最新资讯28at.com
while (this.begin < this.end && !checkFun(arr[this.begin])) {zrY28资讯网——每日最新资讯28at.com
this.begin++;zrY28资讯网——每日最新资讯28at.com
}zrY28资讯网——每日最新资讯28at.com
zrY28资讯网——每日最新资讯28at.com
// 向前移动endzrY28资讯网——每日最新资讯28at.com
while (this.begin < this.end && checkFun(arr[this.end])) {zrY28资讯网——每日最新资讯28at.com
this.end--;zrY28资讯网——每日最新资讯28at.com
}zrY28资讯网——每日最新资讯28at.com
zrY28资讯网——每日最新资讯28at.com
// begin与end都指向了正确的位置zrY28资讯网——每日最新资讯28at.com
if (this.begin < this.end) {zrY28资讯网——每日最新资讯28at.com
// 交换两个元素的顺序zrY28资讯网——每日最新资讯28at.com
[arr[this.begin], arr[this.end]] = [arr[this.end], arr[this.begin]];zrY28资讯网——每日最新资讯28at.com
}zrY28资讯网——每日最新资讯28at.com
}测试用例zrY28资讯网——每日最新资讯28at.com

我们先来测试下奇数在偶数之前的函数处理代码能否正常执行,如下所示:zrY28资讯网——每日最新资讯28at.com

const adjustArrayOrder = new AdjustArrayOrder();zrY28资讯网——每日最新资讯28at.com
// 奇数在前zrY28资讯网——每日最新资讯28at.com
const arr = [2, 4, 5, 6, 7, 8, 9, 11];zrY28资讯网——每日最新资讯28at.com
adjustArrayOrder.reorderOddEven(arr);zrY28资讯网——每日最新资讯28at.com
console.log(arr);zrY28资讯网——每日最新资讯28at.com

执行结果如下所示:zrY28资讯网——每日最新资讯28at.com

zrY28资讯网——每日最新资讯28at.com

最后,我们来测试下reorder函数能否正常执行:zrY28资讯网——每日最新资讯28at.com

负数在数组的最前面// 负数在前zrY28资讯网——每日最新资讯28at.com
const checkMinusNumber = function (val: number) {zrY28资讯网——每日最新资讯28at.com
return val > 0;zrY28资讯网——每日最新资讯28at.com
};zrY28资讯网——每日最新资讯28at.com
const arr = [2, 4, 5, 6, 7, -8, -10 - 12, -2];zrY28资讯网——每日最新资讯28at.com
adjustArrayOrder.reorder(arr, checkMinusNumber);zrY28资讯网——每日最新资讯28at.com
console.log(arr);zrY28资讯网——每日最新资讯28at.com

zrY28资讯网——每日最新资讯28at.com

能被3整除的数在数组的最前面const checkDivisible = function (val: number) {zrY28资讯网——每日最新资讯28at.com
return val % 3 !== 0;zrY28资讯网——每日最新资讯28at.com
};zrY28资讯网——每日最新资讯28at.com
const arr = [2, 4, 5, 6, 3, 6, 9, 12];zrY28资讯网——每日最新资讯28at.com
adjustArrayOrder.reorder(arr, checkDivisible);zrY28资讯网——每日最新资讯28at.com
console.log(arr);zrY28资讯网——每日最新资讯28at.com

zrY28资讯网——每日最新资讯28at.com

示例代码zrY28资讯网——每日最新资讯28at.com

文中所举代码的完整版请移步:zrY28资讯网——每日最新资讯28at.com

AdjustArrayOrder.ts[1]adjustArrayOrder-test.ts[2]参考资料zrY28资讯网——每日最新资讯28at.com

[1]AdjustArrayOrder.ts: https://github.com/likaia/algorithm-practice/blob/e7f6a38021426397af60a73d4c6b8bf88548ba91/src/AdjustArrayOrder.ts#L2zrY28资讯网——每日最新资讯28at.com

[2]adjustArrayOrder-test.ts: https://github.com/likaia/algorithm-practice/blob/e7f6a38021426397af60a73d4c6b8bf88548ba91/src/test-case/adjustArrayOrder-test.ts#L3zrY28资讯网——每日最新资讯28at.com

[3]个人网站: https://www.kaisir.cn/zrY28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-119-2283-0.html调整数组元素顺序,你了解几分?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 数据分析和数据科学的五大不同之处 译文

下一篇: 亚马逊云计算主管:AWS将保持云服务领先地位 不打算将其分拆

标签:
  • 热门焦点
  • 6月iOS设备性能榜:M2稳居榜首 A系列只能等一手3nm来救

    没有新品发布,自然iOS设备性能榜的上榜设备就没有什么更替,仅仅只有跑分变化而产生的排名变动,毕竟苹果新品的发布节奏就是这样的,一年下来也就几个移动端新品,不会像安卓厂商,一
  • 帅气纯真少年!日本最帅初中生选美冠军出炉

    日本第一帅哥初一生选美大赛冠军现已正式出炉,冠军是来自千叶县的宗田悠良。日本一直热衷于各种选美大赛,从&ldquo;最美JK&rdquo;起到&ldquo;最美女星&r
  • JavaScript 混淆及反混淆代码工具

    介绍在我们开始学习反混淆之前,我们首先要了解一下代码混淆。如果不了解代码是如何混淆的,我们可能无法成功对代码进行反混淆,尤其是使用自定义混淆器对其进行混淆时。什么是混
  • 把LangChain跑起来的三个方法

    使用LangChain开发LLM应用时,需要机器进行GLM部署,好多同学第一步就被劝退了,那么如何绕过这个步骤先学习LLM模型的应用,对Langchain进行快速上手?本片讲解3个把LangChain跑起来
  • 共享单车的故事讲到哪了?

    来源丨海克财经与共享充电宝相差不多,共享单车已很久没有被国内热点新闻关照到了。除了一再涨价和用户直呼用不起了。近日多家媒体再发报道称,成都、天津、郑州等地多个共享单
  • 一条抖音4亿人围观 ! 这家MCN比无忧传媒还野

    作者:Hiu 来源:互联网品牌官01 擦边少女空降热搜,幕后推手曝光被网友誉为&ldquo;纯欲天花板&rdquo;的女网红井川里予,近期因为一组哥特风照片登上热搜,引发了一场互联网世界关于
  • 2纳米决战2025

    集微网报道 从三强争霸到四雄逐鹿,2nm的厮杀声已然隐约传来。无论是老牌劲旅台积电、三星,还是誓言重回先进制程领先地位的英特尔,甚至初成立不久的新
  • 滴滴违法违规被罚80.26亿 共存在16项违法事实

    滴滴违法违规被罚80.26亿 存在16项违法事实开始于2121年7月,历经一年时间,网络安全审查办公室对“滴滴出行”网络安全审查终于有了一个暂时的结束。据“网信
  • 微软发布Windows 11新版 引入全新任务栏状态

    近日,微软发布了Windows 11新版,而Build 22563更新主要引入了几周前曝光的平板模式任务栏等,系统更流畅了。更新中,Windows 11加入了专门针对平板优化的任务栏
Top