leetcode88-合并两个有序数组

题目

给你两个有序整数数组 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)

题解

方法 1

调用 splice 和 sort 方法;

var merge = function(nums1, m, nums2, n) {
    nums1.splice(m, nums1.length - m, ...nums2);
    nums1.sort((a, b) => a - b);
};

方法 2

我的理解: 因为是已经排序好的数组,所以可以通过双指针的方法来实现合并。

解这个题目的时候,第一次忘记判断等号了,结果循环出不来了

第二次,发现,当有索引值小于 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--]
        }
    }
};

扩展

1、array 函数

① splice 函数

函数功能: 可以删除或者替换元素(原数组会改变)

入参:start , deletecount, item*

返回:被删除的元素组成的数组

② slice 函数

函数功能:裁剪原数组

入参:begin,end

出参:裁剪元素,是原数组的浅拷贝

浅拷贝:  如果元素是对象,则指向同一个;如果元素是字符串、数字、布尔值(非对象类型),则改变裁剪数组,不会影响元数组。

③ concat 函数

函数功能: 合并两个或多个数组,不改变当前数组

入参: array

出参:合并之后的新数组

2、手写 splice 函数

// 手写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
}

3、手写 findIndex、findLastIndex 、indexOf、lastIndexOf函数

① 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
}

4、手写数组去重函数

① 返回新的数组;

通过 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
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值