日常刷题0x2之未出新手村

117 阅读2分钟

如果不小心网友来到了这里请网友自动飘走,浪费你们时间表示歉意。该系列博客的目的是:想作为自律工具和朋友一起每天刷几道题作为打卡督促的功能,没有什么可参考学习的东西,也不是刷博客量充大佬的目的

题号:31
var nextPermutation = function (nums) {
    //从最右边开始遍历找到一个拐角处(:从大值变小值得过程)
    //找到之后从这个拐角之后的位置到数组结尾处找到一个比拐角下降元素
    //大的一个值,可能多个,但是找到一个最小的,遍历的过程找拐角,
    //说明之前都是递增的,所以从数组最后开始往前找,找到第一个大于
    //拐角之后的元素的值得元素交换,然后把拐角之后的数组从小到大排序
    let right = nums.length - 1
    while (right > 0) {
        let next = right - 1
        if (nums[next] < nums[right]) {
            //翻转
            let begin = right, end = nums.length - 1
            while (end >= begin) {
                if (nums[end] > nums[next]) {
                    //找到一个能和next交换的且比next大的最小的值,交换
                    let tmp = nums[next]
                    nums[next] = nums[end]
                    nums[end] = tmp
                    break
                }
                end--
            }
            end = nums.length - 1
            while (begin <= end) {
                let tmp = nums[begin]
                nums[begin] = nums[end]
                nums[end] = tmp
                begin++
                end--
            }
            return nums
        } else { 
            right = next
        }
    }
    //整个数组遍历完毕都没找到拐角,那么整个数组都是递减的
    //翻转即可
    return nums.reverse()
};
题号:56
var merge = function (intervals) {
    intervals.sort((arr1, arr2) => { 
        return arr1[0] - arr2[0]
    })
    //结果数组是一个栈,栈顶永远是可能要合并的元素
    let result = []
    intervals.forEach((ele,idx,arr) => {
        if (idx == 0) {
            result.push(ele)
        } else { 
            let curArrStart = ele[0]
            let curArrEnd = ele[1]
            let preArr = result[result.length - 1]
            let preArrStart = preArr[0]
            let preArrEnd = preArr[1]
            if (preArrEnd >= curArrStart) {
                //前后有重合,还需判断是包含还是重合部分
                if (curArrEnd <= preArrEnd) {
                    //包含关系
                    //do nothing
                } else { 
                    //重合部分
                    let newArr = [preArrStart, curArrEnd]
                    result.pop()
                    result.push(newArr)
                    
                }
            } else { 
                //没重合
                flag = idx
                result.push(ele)
            }
        }
    });
    return result
};
题号:581
//排序,掐头去尾找差距
var findUnsortedSubarray = function (nums) {
    let arrLen = nums.length
    let oldArr = nums.slice()
    nums.sort((a, b) => { 
        return a-b
    })
    let left = 0
    while (left < arrLen) {
        if (oldArr[left] != nums[left]) {
            let right = arrLen - 1
            while (right >= 0) {
                if (oldArr[right] != nums[right]) {
                    break
                } else { 
                    right--
                }
            }
            return right - left + 1
        } else { 
            left++
        }
    }
    return 0 
};

//不利用对比排序后的差异,就要自己找到边界移动了
var findUnsortedSubarray = function (nums) {
    let arrLen = nums.length
    let stack = []
    let left = 0
    while (left < arrLen) {
        if (left == 0) {
            stack.push(nums[left])
        } else { 
            if (stack[stack.length - 1] > nums[left]) {
                //找到左边开始的拐点
                //开始找右边开始的拐点
                //left和right指向的是下一个元素,当left和right和上次元素比发生拐弯了,要
                //记录上一个元素的位置作为我们要找的最大最小值排序的数组边界
                left -- 
                let right = arrLen - 1
                stack = []
                while (right >= 0) {
                    if (right == arrLen - 1) {
                        stack.push(nums[right])
                    } else { 
                        if (stack[stack.length - 1] < nums[right]) {
                            //找到右边开始的拐点
                            right++
                            //针对这个子数组排序找到最大,最小
                            //然后用最小,最大要左移,右移把最小,最大放到合适的位置
                            //放到合适的位置后那两个边界就是要调整的元素的最小边界
                            let newArr = nums.slice(left, right + 1)
                            newArr.sort((a, b) => { 
                                return a - b
                            })
                            let min = newArr[0]
                            let max = newArr[newArr.length - 1]

                            let left1 = left - 1
                            let right1 = right + 1
 
                            while (left1 >= 0) {
                                if (min >= nums[left1]) {
                                    break
                                } else { 
                                    left1 --
                                }
                            }
                            //找右边界
                            while (right1 < arrLen) {
                                if (max <= nums[right1]) {
                                    break
                                } else { 
                                    right1++
                                }
                            }
                            return (right1 - 1) - (left1 + 1) + 1
                        } else { 
                            stack.push(nums[right])
                        }
                    }
                    right --
                }
            } else { 
                stack.push(nums[left])
            }
        }
        left ++
    }
    return 0
};