给你两个有序整数数组
nums1
和nums2
,请你将nums2
合并到nums1
中,使num1
成为一个有序数组。说明:
初始化
nums1
和nums2
的元素数量分别为m
和n
。
你可以假设nums1
有足够的空间(空间大小大于或等于m + n
)来保存nums2
中的元素。示例:
输入: nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6], n = 3 输出: [1,2,2,3,5,6]
我的第一想法是,删除 nums1 数组后面的 0, 将 nums2 中的每一个数和 nums1 中的数比较,找到插入位置,然后插入数值。
双层循环实现。
时间复杂度为 O(m*n)
调用 splice 和 sort 方法;
var merge = function(nums1, m, nums2, n) {
nums1.splice(m, nums1.length - m, ...nums2);
nums1.sort((a, b) => a - b);
};
我的理解: 因为是已经排序好的数组,所以可以通过双指针的方法来实现合并。
解这个题目的时候,第一次忘记判断等号了,结果循环出不来了
第二次,发现,当有索引值小于 0 的时候,默认赋值为 0 了,没有考虑到可能出现负值的情况
第三次,当改为 当存在索引值小于 0 的时候,默认为另一个数组的值。 但这样,索引就不知道减哪一个了。
var merge = function(nums1, m, nums2, n) {
let num1Index = m - 1;
let num2Index = n-1;
let curIndex = m + n - 1;
while(num1Index >= 0 || num2Index >= 0) {
// 小于 0 的时候,默认赋值为另外一个数组的值
const num1 = num1Index < 0 ? nums2[num2Index] : nums1[num1Index]
const num2 = num2Index < 0 ? nums1[num1Index] : nums2[num2Index]
if(num1 >= num2) {
nums1[curIndex--] = num1
// 两个值相等,可能是因为其中一个 索引小于 0
num1Index < 0 ? num2Index-- : num1Index--
}else {
nums1[curIndex--] = num2
num2Index--
}
}
};
但我的代码其实可读性很差,而且各种边界情况都得考虑。
能不能先排除特殊情况呢?
var merge = function(nums1, m, nums2, n) {
let num1Index = m - 1;
let num2Index = n-1;
let curIndex = m + n - 1;
while(num1Index >= 0 || num2Index >= 0) {
// 当 num1Index 小于 0 时,直接取 num2
if(num1Index < 0) {
nums1[curIndex--]= nums2[num2Index--]
}
// 当 num2Index 小于 0 时,直接取 num1
if(num2Index < 0) {
nums1[curIndex--]= nums1[num1Index--]
}
// 只有当两者都大于 0 的时候,才进行比较
if(num1Index >= 0 && num2Index >= 0){
nums1[curIndex--] = nums1[num1Index] > nums2[num2Index] ? nums1[num1Index--] : nums2[num2Index--]
}
}
};
① splice 函数
函数功能: 可以删除或者替换元素(原数组会改变)
入参:start , deletecount, item*
返回:被删除的元素组成的数组
② slice 函数
函数功能:裁剪原数组
入参:begin,end
出参:裁剪元素,是原数组的浅拷贝
浅拷贝: 如果元素是对象,则指向同一个;如果元素是字符串、数字、布尔值(非对象类型),则改变裁剪数组,不会影响元数组。
③ concat 函数
函数功能: 合并两个或多个数组,不改变当前数组
入参: array
出参:合并之后的新数组
// 手写splice 函数
Array.prototype._splice = function(start, count = 0) {
let arr = this
let insertLen = arguments.length - 2
let temp = []
const delList = []
// 如果 start 大于 数组长度
if(start >= arr.length) {
for(let j = 2; j < arguments.length; j++){
arr.push(arguments[j])
}
return delList
}
if(start < 0) {
start = arr.length + start < 0 ? 0 : arr.length + start
}
for(let i = 0; i < arr.length; i++) {
if(i <= start) {
temp[i] = arr[i]
}
if(i > start ) {
// 先删除
if(count > 0) {
delList.push(arr[i])
count--
if(count ===0 && insertLen) {
for(let j = 2; j < arguments.length; j++){
temp.push(arguments[j])
insertLen--
}
}
}
// 再添加新的
else {
temp[i] = arr[i]
}
}
}
arr = temp
return delList
}
① findIndex
函数功能: 发现满足条件的第一个元素,如果不存在则返回 -1
入参: 函数
// 注意:不要写成箭头函数,箭头函数没有 this
Array.prototype._findIndex = function (callback) {
const arr = this;
for(let i = 0; i < arr.length; i++) {
if(callback(arr[i], i, arr)){
return i
}
}
return -1
}
② findLastIndex
函数功能: 发现最后一个满足条件的元素,如果不存在,则返回 -1
入参: 函数
// 注意:不要写成箭头函数,箭头函数没有 this
// 从尾部开始查找
Array.prototype._findIndex = function (callback) {
const arr = this;
for(let i = arr.length - 1; i >= 0; i--) {
if(callback(arr[i], i, arr)){
return i
}
}
return -1
}
③ indexOf
函数功能: 发现第一个等于查找元素的索引,不存在,则返回 -1
入参: ① 查找元素 ② 开始查找位置
Array.prototype._indexOf = function(searchItem, fromIndex) {
const arr = this
if(fromIndex >= arr.length || fromIndex < -arr.length) return -1
let start = fromIndex < 0 ? arr.length + fromIndex : fromIndex
for(start; start < arr.length; start++) {
if(searchItem === arr[start]) {
return start
}
}
return -1
}
③ lastIndexOf
函数功能: 发现等于最后一个等于查找元素的索引,不存在,则返回 -1
入参: ① 查找元素 ② 开始查找位置
Array.prototype._lastIndexOf = function(searchItem, fromIndex) {
const arr = this
if(fromIndex >= arr.length || fromIndex < -arr.length) return -1
let start = fromIndex < 0 ? arr.length + fromIndex : fromIndex
for(let i = arr.length; i >= start; i--) {
if(searchItem === arr[start]) {
return start
}
}
return -1
}
① 返回新的数组;
通过 set 方法
Array.prototype._unique = function() {
const arr = this
return Array.from(new Set(arr))
}
通过 filter 方法
Array.prototype._unique = function() {
const arr = this
return arr.filter(
(item, index, array)=>array.indexOf(item) === index
)
}
通过 reduce 方法
Array.prototype._unique = function() {
const arr = this
return arr.sort().reduce((acc, cur) => {
if (acc.length === 0 || acc[acc.length - 1] !== cur) {
acc.push(cur);
}
return acc
}, [])
}
② 改变原数组
const removeDuplicates = (nums) => {
let len = nums.length - 1
for(let i = len; i>=0; i--) {
if(nums.indexOf(nums[i]) != i) {
nums[i] = nums[len --]
}
}
// 删除重复项
nums.splice(len+1)
return nums
}
// 测试
removeDuplicates([1, 2, 3, 1, 3])
// [1, 2, 3]
5、手写数组 扁平函数
function flat(arr, depth = 1) {
return depth > 0
? arr.reduce((acc, cur) => {
if(Array.isArray(cur)) {
return [...acc, ...flat(cur, depth-1)]
}
return [...acc, cur]
} , [])
: arr
}