我举个例子,比如这题,旋转数组:
https://leetcode-cn.com/probl...
这里我用 JavaScript 语言来实现,先不看算法写的好不好,就看一下实现方式的对比。
我写的第一种解法是:
var rotate = function(nums, k) {
let len = nums.length;
for (let i = 0; i < k; i++) {
let last = nums[len - 1];
// 数组右移算法
for (let j = len - 1; j > 0; j--) {
nums[j] = nums[j - 1];
}
nums[0] = last;
}
};
这样的算法有个好处,就是语言移植性很好,每个语言都有 for 循环,算法里面也没有用语言提供的函数。
作为对比,使用语言提供的函数来写另外一种解法:
var rotate = function(nums, k) {
var prev = nums.slice(0, nums.length - 3);
const remain = nums.slice(nums.length - 3);
// 两数组连接起来
const newArr = remain.concat(prev);
for(let i = 0; i < nums.length; i++) {
nums[i] = newArr[i];
}
};
看上去使用语言提供的函数来解算法似乎比一般的写法要高级一些。
我不明白的是,咱们在做算法训练的时候,到底要不要用语言提供的函数呢?
市面上有些书名叫:《算法-xx语言实现》
是不是这些书里面的算法实现都是使用语言提供的函数来写的呀?
我个人是倾向于优先使用一般的解法,把一般的解法写出来后,才会来考虑使用擅长的语言提供的函数来写一个感觉更高级的实现。
不知道各位大神是怎么思考的?求教。
用和不用内置函数,其实是表面的。
算法,通常我们考虑时间复杂度、空间复杂度。
本身来说,算法是脱离语言的,和语言没有任何关系的。
通常设计一个算法,用内置函数,那你得明白内置函数的实现原理、复杂度等,这样才能衡量你设计的算法的复杂度。
就比如一个JS里(不考虑稀疏数组的话)push函数,时间复杂度摊销O(1),unshift函数,时间复杂度O(n),这些函数可以用,但是在衡量算法优劣指标的时候,要考虑这些因素的影响,以及自己实现会不会比内置函数更优。
至于移植性,在不同语言之间通常是不存在的,也是不考虑的。移植性通常是对于同一门语言在不同平台之间。