算法练习day1

314 阅读2分钟

一、数组理论基础

数组是存储相同类型元素且在内存地址上连续的集合

数组可以方便的根据下标索引获取对应的数据

数组在删除或者添加元素时,需要移动其他元素的地址

二、二分查找

问题要点

二分查找的关键是根据定义好的区间(不变量),在循环中操作,保证循环不变量

左闭右闭

时间复杂度:O(log n),空间复杂度:O(1)

/**
 * 左闭右闭
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var search = function(nums, target) {
    let left = 0
    let right = nums.length - 1
    while(left <= right) {
        // let middle = Math.floor((left + right) / 2)
        let middle = left + ((right - left) >> 1) // 提升效率
        if (nums[middle] === target) {
            return middle
        } else if(nums[middle] > target) {
            right = middle - 1
        } else {
            left = middle + 1
        }
    }
    return -1
};

左闭右开

时间复杂度:O(log n),空间复杂度:O(1)

/**
 * 左闭右开
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var search = function(nums, target) {
    let left = 0
    let right = nums.length
    while(left < right) {
        // let middle = Math.floor((left + right) / 2)
        let middle = left + ((right - left) >> 1)
        if (nums[middle] === target) {
            return middle
        } else if(nums[middle] > target) {
            right = middle
        } else {
            left = middle + 1
        }
    }
    return -1
};

三、移除元素

问题要点

数组元素在内存中的地址是连续的,所以不能单独删除某个元素,只能覆盖

暴力求解

时间复杂度:O(n^2),空间复杂度:O(1)

/**
 * 暴力求解
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function(nums, val) {
    let len = nums.length
    for(let i = 0; i < len; i++) {
        if(nums[i] === val) {
            for(let j = i + 1; j < len; j++) {
                nums[j - 1] = nums[j]
            }
            i--
            len--
        }
    }
    return len
};

双指针法

双指针法是通过一个慢指针和一个快指针在一个循环下完成两个循环的操作,常用于数组,字符串和链表的操作

时间复杂度:O(n),空间复杂度:O(1)

/**
 * 快慢指针
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function(nums, val) {
    let len = nums.length
    let slow = 0
    let fast = 0
    while(fast < len) {
        if (nums[fast] !== val) {
            nums[slow] = nums[fast]
            slow++
        }
        fast++
    }
    return slow
};

对撞指针

时间复杂度:O(n),空间复杂度:O(1)

/**
 * 对撞指针
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function(nums, val) {
    let len = nums.length
    let left = 0
    let right = len - 1
    while(left <= right) {
        while(left <= right && nums[left] !== val) {
            left++
        }
        while(left <= right && nums[right] === val) {
            right--
        }
        if(left < right) {
            nums[left++] = nums[right--]
        }
    }
    return left
};