JS算法练习3.8

Leetcode 54 螺旋矩阵

let matrix = [
    [1, 2, 3, 4, 5],
    [16, 17, 18, 19, 6],
    [15, 24, 25, 20, 7],
    [14, 23, 22, 21, 8],
    [13, 12, 11, 10, 9]
];

function Spiralorder(matrix) {
    if (!matrix.length || !matrix[0].length) return [];

    const Spiralorder = [];
    let rows = matrix[0].length,
        columns = matrix.length;
    let top = 0,
        bottom = rows - 1,
        left = 0,
        right = columns - 1;

    while (top <= bottom && left <= right) {

        for (let j = left; j <= right; j++)
            Spiralorder.push(matrix[top][j])

        for (let i = top + 1; i <= bottom; i++)
            Spiralorder.push(matrix[i][right]);

        if (top < bottom && left < right) {
            for (let j = right - 1; j > left; j--)
                Spiralorder.push(matrix[bottom][j]);
            for (let i = bottom; i > top; i--)
                Spiralorder.push(matrix[i][left]);
        }

        top++, bottom--, left++, right--;
    }

    return Spiralorder;
}

let a = Spiralorder;
console.log(a(matrix));
//console.log(Spiralorder(matrix));

二分查找

function BinarySearch(arr, target) {
    let left = 0,
        right = arr.length - 1;

    while (left <= right) {
        let mid = Math.round((left + right) / 2); //JS除法不是去余的
        if (arr[mid] === target) //在JS中不要使用==比较数组
            return mid;
        else if (target > arr[mid])
            left = mid + 1;
        else
            right = mid - 1;
    }

    return false;
}

let arr = [1, 2, 3, 4, 5, 9, 10, 11, 13, 20, 21, 23];
console.log(BinarySearch(arr, 3));
function Find(target, array) {
    let i = 0;
    let j = array[i].length - 1;
    while (i < array.length && j >= 0) {
        if (array[i][j] < target) {
            i++;
        } else if (array[i][j] > target) {
            j--;
        } else {
            return true;
        }
    }
    return false;
}

//测试用例
console.log(Find(10, [
    [1, 2, 3, 4], 
    [5, 9, 10, 11], 
    [13, 20, 21, 23]
    ])
);

Leetcode 283 去除零

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
    let count=0;
    let len=nums.length;

    for(let i=0;i<len;i++){
        if(nums[i]===0){
            nums.splice(i,1);
            count++;
            i--;//注意此处,splice之后数组有变化
        }
    }
        
    while(count){
        nums.push(0);
        count--;
    }
};

注:此题有优化思路,利用索引指针,交换0和其他元素

Leetcode 27 移除元素

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

Leetcode 26 删除有序数组中重复项

/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function(nums) {
    nums=Array.from(new Set(nums));
    return nums.length;
};

这里使用ES6新特性就行了,不必双指针,但在力扣的传参机制下过不了,原因如下:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 
int len = removeDuplicates(nums);
// 在函数里修改输入数组对于调用者是可见的。 
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。 
for(int i = 0; i < len; i++) {
     print(nums[i]); 
}

使用Set,并不能改变数组原有顺序,需要使用指针调整数组元素位置才符合此处用例,即不使用额外空间、原地修改数组。

Leetcode 80 删除有序数组中重复项II

和上一题不同的是,每个重复元素最多出现两次
这里就必须用到指针了

function RemoveDuplicatesII(arr) {
    let len = arr.length;

    if (len <= 2) return len;

    let slow = 2,
        fast = 2;

    while (fast < len) {
        if (arr[slow - 2] != arr[fast]) {
            arr[slow] = arr[fast];
            slow++;
        }
        fast++;
    }

    return slow;
}

快速排序

function quickSort(arr, left = 0, right = arr.length - 1) {
    if (arr.length > 1) {
        const lineIndex = partition(arr, left, right); //下一次划分左右子数组的索引位

        if (left < lineIndex - 1)
            quickSort(arr, left, lineIndex - 1);
        if (lineIndex < right)
            quickSort(arr, lineIndex, right);
    }

    return arr;
}

function partition(arr, left, right) {
    let pivot = arr[Math.floor((left + right) / 2)]; //基准值默认取中间位置元素
    let i = left,
        j = right;

    while (i <= j) { //当左右指针不越界时
        while (arr[i] < pivot) i++; // 左指针所指元素若小于基准值,则右移左指针
        while (arr[j] > pivot) j--; // 右指针所指元素大于基准值,则左移右指针

        if (i <= j) { //若i<=j,则意味着基准值左边存在较大元素或右边存在较小元素,交换两个元素确保左右两侧有序
            [arr[i], arr[j]] = [arr[j], arr[i]];
            i++, j--;
        }
    }

    return i; //返回左指针索引作为下一次划分左右子数组的依据
}

arr = [4, 7, 2, 6, 9, 3, 6, 0, 5, 6, 3];
quickSort(arr, 0, arr.length - 1);
console.log(arr);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值