[Algorithm progress 213/400 (〃'▽'〃)], keep going!

136. Numbers that only appear once

Given an array of non-empty integers, except for an element that appears only once, every other element appears twice. Find the element that appears only once.

illustrate:
Your algorithm should have linear time complexity. Can you do this without using extra space?

示例 1:

输入: [2,2,1]
输出: 1

示例 2:
输入: [4,1,2,1,2]
输出: 4

Hash table

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function (nums) {
    let hash = {}
    for (let i = 0; i < nums.length; i++) {
        hash[nums[i]] ? hash[nums[i]]++ : hash[nums[i]] = 1
    }
    for (let j in hash) {
        if (hash[j] === 1) {
            return j
        }
    }
};

XOR

var singleNumber = function (nums) {
    let ans = nums[0]
    for (let i = 1; i < nums.length; i++) {
        ans = ans ^ nums[i]
    }
    return ans
};

278. The first wrong version

You are a product manager and are currently leading a team to develop new products. Unfortunately, the latest version of your product did not pass the quality inspection. Since each version is developed based on the previous version, all versions after the wrong version are wrong.

Suppose you have n versions [1, 2, ..., n], and you want to find the first wrong version that caused all subsequent versions to go wrong.
You can call the bool isBadVersion(version) interface to determine whether the version number version is wrong in the unit test. Implement a function to find the first wrong version. You should minimize the number of calls to the API.

示例 1:
输入:n = 5, bad = 4
输出:4
解释:
调用 isBadVersion(3) -> false 
调用 isBadVersion(5) -> true 
调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。

示例 2:
输入:n = 1, bad = 1
输出:1

dichotomy

var solution = function (isBadVersion) {
    return function (n) {
        let left = 1, right = n
        while (left < right) {
            const mid = Math.floor(left + (right - left) / 2)
            if (isBadVersion(mid)) {
                right = mid
            } else {
                left = mid + 1
            }
        }
        return left
    };
};

704. Binary Search

Given an n-element ordered (ascending) integer array nums and a target value target, write a function to search for target in nums, and return the subscript if the target value exists, otherwise return -1.

示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2:

输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

提示:

    你可以假设 nums 中的所有元素是不重复的。
    n 将在 [1, 10000]之间。
    nums 的每个元素都将在 [-9999, 9999]之间。

dichotomy

var search = function (nums, target) {
    let low = 0, high = nums.length - 1
    while (low <= high) {
        const mid = Math.floor((high - low) / 2) + low
        const num = nums[mid]
        if (num === target) {
            return mid
        } else if (num > target) {
            high = mid - 1
        } else if (num < target) {
            low = mid + 1
        }
    }
    return -1
};

findIndex

var search = function(nums, target) {
    return nums.findIndex(v=>v===target)
};

indexOf

var search = function(nums, target) {
    return nums.indexOf(target)
};

for loop

var search = function (nums, target) {
    for (let i = 0; i < nums.length; i++) {
        if(nums[i] === target) return i
    }
    return -1
};

35. Search for Insertion Location

Given a sorted array and a target value, find the target value in the array and return its index. If the target value does not exist in the array, return the position where it will be inserted in order.

Please use an algorithm with a time complexity of O(log n).

示例 1:
输入: nums = [1,3,5,6], target = 5
输出: 2

示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1

示例 3:
输入: nums = [1,3,5,6], target = 7
输出: 4

示例 4:
输入: nums = [1,3,5,6], target = 0
输出: 0

示例 5:
输入: nums = [1], target = 0
输出: 0

提示:

    1 <= nums.length <= 104
    -104 <= nums[i] <= 104
    nums 为无重复元素的升序排列数组
    -104 <= target <= 104

filter

var searchInsert = function (nums, target) {
    return nums.filter(v => v < target).length
};

dichotomy

var searchInsert = function (nums, target) {
    let len = nums.length
    if (len === 0) return 0
    let left = 0, right = len-1
    while (left < right) {
        // const mid = (left + right) >> 1
        const mid = Math.floor((right - left) / 2 + left)
        if (nums[mid] >= target) {
            right = mid
        } else if(nums[mid] < target) {
            left = mid + 1
        }
    }
    if (nums[right] < target) {
        return right + 1
    }
    return right
};

977. Squaring an Ordered Array

Give you an integer array nums sorted in non-decreasing order, and return a new array composed of the square of each number, and it is required to also sort in non-decreasing order.

示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

提示:
    1 <= nums.length <= 104
    -104 <= nums[i] <= 104
    nums 已按 非递减顺序 排序
    
进阶:

    请你设计时间复杂度为 O(n) 的算法解决本问题

Double pointer

var sortedSquares = function (nums) {
    let i = 0, j = nums.length - 1, res = [], k = nums.length - 1
    while (i <= j) {
        if (nums[i] * nums[i] > nums[j] * nums[j]) {
            res[k--] = nums[i] * nums[i++]
        } else {
            res[k--] = nums[j] * nums[j--]
        }
    }
    return res
};

reduce+sort

var sortedSquares = function (nums) {
    return nums.reduce((acc, prev) => acc.concat(prev * prev), []).sort((a,b)=>a-b)
};

896. Monotone Sequence

If the array is monotonically increasing or monotonically decreasing, then it is monotonic. If for all i <= j, A[i] <= A[j], then the array A is monotonically increasing. If for all i <= j, A[i]> = A[j], then the array A is monotonically decreasing. It returns true when the given array A is a monotonic array, otherwise it returns false.

示例 1:
输入:[1,2,2,3]
输出:true

示例 2:
输入:[6,5,4,4]
输出:true

示例 3:
输入:[1,3,2]
输出:false

示例 4:
输入:[1,2,4,5]
输出:true

示例 5:
输入:[1,1,1]
输出:true

提示:

    1 <= A.length <= 50000
    -100000 <= A[i] <= 100000
var isMonotonic = function (nums) {
    let inc =true,dec = true
    for(let i=0;i<nums.length;i++){
        if(nums[i+1]-nums[i]>0){
            dec = false
        }
        if(nums[i]-nums[i+1]>0){
            inc = false
        }
    }
    return dec || inc
};

941. Valid Mountain Range Array

Given an integer array arr, it returns true if it is a valid mountain array, otherwise it returns false.

Let us recap, if A satisfies the following conditions, then it is an array of mountains:

    arr.length >= 3
    在 0 < i < arr.length - 1 条件下,存在 i 使得:
        arr[0] < arr[1] < ... arr[i-1] < arr[i]
        arr[i] > arr[i+1] > ... > arr[arr.length - 1]
示例 1:
输入:arr = [2,1]
输出:false

示例 2:
输入:arr = [3,5,5]
输出:false

示例 3:
输入:arr = [0,3,2,1]
输出:true

提示:

    1 <= arr.length <= 104
    0 <= arr[i] <= 104

Double pointer

const validMountainArray = (A) => {
    const n = A.length;
    let i = 0;
    let j = n - 1;

    while (i + 1 < n && A[i] < A[i + 1]) {
        i++;
    }
    while (j - 1 >= 0 && A[j - 1] > A[j]) {
        j--;
    }
    if (i != 0 && i == j && j != n - 1) {
        return true;
    }
    return false;
};

167. Sum of Two Numbers II-Input Ordered Array

Given an integer array numbers arranged in non-decreasing order, please find two numbers from the array that satisfy the sum of the target number target.

The function should return the subscript values of these two numbers in the form of an integer array of length 2. The subscript of numbers starts counting from 1, so the answer array should satisfy 1 <= answer[0] <answer[1] <= numbers.length.

You can assume that each input only corresponds to a unique answer, and you cannot reuse the same elements.

示例 1:
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

示例 2:
输入:numbers = [2,3,4], target = 6
输出:[1,3]

示例 3:
输入:numbers = [-1,0], target = -1
输出:[1,2]

提示:

    2 <= numbers.length <= 3 * 104
    -1000 <= numbers[i] <= 1000
    numbers 按 非递减顺序 排列
    -1000 <= target <= 1000
    仅存在一个有效答案

Double pointer

var twoSum = function (numbers, target) {
    let i = 0, j = numbers.length-1;
    while (i <= j) {
        if (numbers[i] + numbers[j] > target) {
            j--
        } else if (numbers[i] + numbers[j] === target) {
            return [++i, ++j]
        } else {
            i++
        }
    }
};

1984. Minimum difference in student scores

Give you an integer array nums whose subscript starts from 0, where nums[i] represents the score of the i-th student. The other gives you an integer k.

Select the scores of any k students from the array to minimize the difference between the highest score and the lowest score among these k scores.
Return the smallest possible difference.

示例 1:

输入:nums = [90], k = 1
输出:0
解释:选出 1 名学生的分数,仅有 1 种方法:
- [90] 最高分和最低分之间的差值是 90 - 90 = 0
可能的最小差值是 0

示例 2:
输入:nums = [9,4,1,7], k = 2
输出:2
解释:选出 2 名学生的分数,有 6 种方法:
- [9,4,1,7] 最高分和最低分之间的差值是 9 - 4 = 5
- [9,4,1,7] 最高分和最低分之间的差值是 9 - 1 = 8
- [9,4,1,7] 最高分和最低分之间的差值是 9 - 7 = 2
- [9,4,1,7] 最高分和最低分之间的差值是 4 - 1 = 3
- [9,4,1,7] 最高分和最低分之间的差值是 7 - 4 = 3
- [9,4,1,7] 最高分和最低分之间的差值是 7 - 1 = 6
可能的最小差值是 2

提示:
    1 <= k <= nums.length <= 1000
    0 <= nums[i] <= 1
var minimumDifference = function (nums, k) {
    nums = nums.sort((a, b) => a - b)
    let ret = Infinity
    for (let i = 0; i + k - 1 < nums.length; i++) {
        if (nums[i + k - 1] - nums[i] < ret) {
            ret = nums[i + k - 1] - nums[i];
        }
    }
    return ret
};

1436. Travel Terminal

Give you a tourist route map. The routes in the route map are represented by the array paths, where paths[i] = [cityAi, cityBi] means that the route will go directly from cityAi to cityBi. Please find out the destination of this trip, that is, a city that does not have any routes to other cities.

The title data guarantees that the route map will form a route without loops, so there is exactly one travel terminal.

示例 1:
输入:paths = [["London","New York"],["New York","Lima"],["Lima","Sao Paulo"]]
输出:"Sao Paulo" 
解释:从 "London" 出发,最后抵达终点站 "Sao Paulo" 。本次旅行的路线是 "London" -> "New York" -> "Lima" -> "Sao Paulo" 。

示例 2:
输入:paths = [["B","C"],["D","B"],["C","A"]]
输出:"A"
解释:所有可能的线路是:
"D" -> "B" -> "C" -> "A". 
"B" -> "C" -> "A". 
"C" -> "A". 
"A". 
显然,旅行终点站是 "A" 。

示例 3:
输入:paths = [["A","Z"]]
输出:"Z"

提示:
    1 <= paths.length <= 100
    paths[i].length == 2
    1 <= cityAi.length, cityBi.length <= 10
    cityAi != cityBi
    所有字符串均由大小写英文字母和空格字符组成。

Set

var destCity = function(paths) {
    let ans = new Set()
    for(let i of paths){
        ans.add(i[0])
    }
    for(let j  of paths){
        if(!ans.has(j[1])){
            return j[1]
        }
    }
    return ''
};

876. The middle node of the linked list

Given a non-empty singly linked list whose head node is head, return the middle node of the linked list.

If there are two intermediate nodes, return to the second intermediate node.

示例 1:
输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.

示例 2:
输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。

提示:
    给定链表的结点数介于 1 和 100 之间。
var middleNode = function(head) {
    let slow = head,fast = head;
    while(fast!==null && fast.next!==null){
        slow = slow.next;
        fast = fast.next.next;
    }
    return slow
};

374. Guess the size of the number

374. Guess the size of the number

The rules of the number guessing game are as follows:

每轮游戏,我都会从 1 到 n 随机选择一个数字。 请你猜选出的是哪个数字。
如果你猜错了,我会告诉你,你猜测的数字比我选出的数字是大了还是小了。

You can get the guess result by calling a predefined interface int guess(int num). The return value has 3 possible situations (-1, 1 or 0):

-1:我选出的数字比你猜的数字小 pick < num
1:我选出的数字比你猜的数字大 pick > num
0:我选出的数字和你猜的数字一样。恭喜!你猜对了!pick == num

Return the number I selected.

示例 1:
输入:n = 10, pick = 6
输出:6

示例 2:
输入:n = 1, pick = 1
输出:1

示例 3:
输入:n = 2, pick = 1
输出:1

示例 4:
输入:n = 2, pick = 2
输出:2

提示:
    1 <= n <= 231 - 1
    1 <= pick <= n

dichotomy

var guessNumber = function (n) {
    let left = 1, right = n
    while (left < right) {
        const mid = Math.floor((right - left) / 2 + left)
        if (guess(mid) <= 0) {
            right = mid
        } else {
            left = mid + 1
        }
    }
    return left
};

405. Number conversion to hexadecimal number

405. Number conversion to hexadecimal number

Given an integer, write an algorithm to convert this number into a hexadecimal number. For negative integers, we usually use one's complement arithmetic.

Notice:

十六进制中所有字母(a-f)都必须是小写。
十六进制字符串中不能包含多余的前导零。如果要转化的数为0,那么以单个字符'0'来表示;对于其他情况,十六进制字符串中的第一个字符将不会是0字符。 
给定的数确保在32位有符号整数范围内。
不能使用任何由库提供的将数字直接转换或格式化为十六进制的方法。
示例 1:
输入:
26

输出:
"1a"

示例 2:
输入:
-1

输出:
"ffffffff"
var toHex = function (num) {
    const hex = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f']
    if (num === 0) {
        return '0'
    }
    let ans = "";
    if (num < 0) {
        num = Math.pow(2, 32) - Math.abs(num);
    }
    while (num) {
        ans += hex[num % 16];
        num = Math.floor(num / 16);
    }
    return ans.split("").reverse().join("");
};

643. Maximum average of sub-array I

Give you an integer array nums consisting of n elements and an integer k. Please find the continuous sub-array with the largest average number and length k, and output the largest average number.

Any answer with an error of less than 10-5 will be considered the correct answer.

示例 1:
输入:nums = [1,12,-5,-6,50,3], k = 4
输出:12.75
解释:最大平均数 (12-5-6+50)/4 = 51/4 = 12.75

示例 2:

输入:nums = [5], k = 1
输出:5.00000

提示:

    n == nums.length
    1 <= k <= n <= 105
    -104 <= nums[i] <= 104
var findMaxAverage = function (nums, k) {
    let max = ans = [...nums].slice(0, k).reduce((acc, prev) => acc += prev);
    for (let i = 1; i <= nums.length - k; i++) {
        ans = ans - nums[i - 1] + nums[i + k - 1]
        max = Math.max(ans, max)
    }
    return max / k
};

283. Moving Zero

Given an array of nums, write a function to move all zeros to the end of the array while maintaining the relative order of non-zero elements.

示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

说明:
    必须在原数组上操作,不能拷贝额外的数组。
    尽量减少操作次数。
var moveZeroes = function (nums) {
    let i = 0, j = 0;
    while (i < nums.length) {
        if (nums[i] != 0) {
            nums[j++] = nums[i]
        }
        i++
    }
    for (let a = j; a < nums.length; a++) {
        nums[a] = 0
    }
    return nums
};

微芒不朽
1.2k 声望1.3k 粉丝