前端知识点2——手撕算法

 

目录

 

一、排序

1、冒泡排序

2、快速排序

3、选择排序

4、插入排序

5、归并排序

 6、堆排序

二、字符串全排列

1、广度优先搜索

2、深度优先搜索

三、查找

1、二分查找

2、找出出现次数最多的元素 

四、动态规划

1、跳台阶

2、斐波那契数列

3、连续子数组的最大和

五、二叉树

1、二叉树最小深度

2、二叉树最大深度

3、二叉树的中序,前序,后序遍历

(1)前序遍历

(2)中序遍历

(3)后序遍历

4、另一棵树是否存在相同子树

六、链表

1、合并两个有序列表

2、判断是否为环形链表

3、是否为回文链表

七、字符串

1.反转字符串

2、最长公共前缀

3、最长回文子串

八、栈

1、基本计算器

2、有效括号

九、滑动窗口

1、无重复字符的最长子串

2、和为s的连续正序序列

3、和为k的子数组

十、回溯

1、全排列

2、全排列||

3、组合

4、组合总和

十一、股票

1、买卖股票的最佳时机

2、买卖股票的最佳时机||

3、买卖股票最佳时机含冷冻期

十二、数组

1、两数之和

2、移动零

3、数组形式的整数加法

4、公平的糖果交换

5、 合并两个有序数组

6、只出现一次的数字

7、子数组最大平均数 I

十三、阶乘后的零


一、排序

1、冒泡排序

2、快速排序

 快速排序,说白了就是给基准数据找其正确索引位置的过程

3、选择排序

<script>
        //选择排序:每次选择每轮最小(最大)的数字放到每轮的最前面去
        //升序
        function selectSort(nums) {
            for (let i = 0; i < nums.length; i++) {
                let index = i
                for (let j = nums.length; j > i; j--) {
                    if (nums[j] < nums[index]) {
                        index = j
                    }
                }
                let temp = nums[i]
                nums[i] = nums[index]
                nums[index] = temp
            }
        }

        //test
        nums = [6, 3, 5, 4, 1, 2];
        selectSort(nums);
        console.log(nums);
    </script>

4、插入排序

<script>
        //插入排序:从第二个元素开始 把元素插入到合适的位置
        //升序
        function insertSort(nums) {
            for (let i = 1; i < nums.length; i++) {
                for (let j = i; j > 0; j--) {
                    if (nums[j] < nums[j - 1]) {
                        let temp = nums[j]
                        nums[j] = nums[j - 1]
                        nums[j - 1] = temp
                    }

                }
            }
        }
        //test
        nums = [6, 3, 5, 4, 1, 2]
        insertSort(nums)
        console.log(nums)
    </script>

5、归并排序

<script>
        //升序
        function mergeSort(nums) {
            if (nums.length < 2) return nums

            let middle = Math.floor(nums.length / 2)
            let left = nums.slice(0, middle)
            let right = nums.slice(middle)

            return merge(mergeSort(left), mergeSort(right))
        }

        function merge(left, right) {
            let res = []
            while (left.length > 0 && right.length > 0) {
                if (left[0] <= right[0]) {
                    res.push(left.shift())
                } else {
                    res.push(right.shift())
                }
            }
            return res.concat(left).concat(right)
        }

        //test
        nums = [6, 3, 5, 4, 1, 2]
        let result = mergeSort(nums)
        console.log(result)
    </script>

 6、堆排序

<script>
        //堆是一棵顺序存储的二叉树
        //其中每个节点的关键字都不大于其子节点的关键字,这样的堆称为小顶堆(用于降序)
        //其中每个节点的关键字都不小于其自己点的关键字,这样的堆称为大顶堆(用于升序)

        //降序
        function heapSort(nums) {
            if (nums.length <= 1) return nums;
            buildHeap(nums) //建造小顶堆
                //小顶堆排序
            let heapSize = nums.length - 1
            for (let i = 0; i < nums.length; i++) {
                swap(nums, 0, heapSize--) //将当前小顶堆的最后一个元素和第一个交换
                shiftDown(nums, 0, heapSize)
            }
        }
        //小顶堆
        function buildHeap(nums) {
            let len = nums.length
            for (let i = Math.floor(len / 2) - 1; i >= 0; i--) {
                shiftDown(nums, i, len)
            }
        }

        function shiftDown(nums, i, heapSize) {
            let left = 2 * i + 1 //左叶子索引号
            let right = 2 * i + 2 //右叶子索引号
            let smallest = i //当前最大值索引号
            if (left < heapSize && nums[left] < nums[smallest]) {
                smallest = left
            }
            if (right < heapSize && nums[right] < nums[smallest]) {
                smallest = right
            }
            if (smallest != i) {
                swap(nums, smallest, i)
                shiftDown(nums, smallest, heapSize)
            }
        }

        function swap(nums, largest, i) {
            let temp = nums[largest]
            nums[largest] = nums[i]
            nums[i] = temp
        }

        //test
        nums = [5, 1, 4, 2, 8, 11, 2, 3];
        heapSort(nums)
        console.log(nums);
    </script>

二、字符串全排列

1、广度优先搜索

<script>
        function bfs(str) {
            if (str.length == 1) return [str]
            let res = []
            for (let i in str) {
                // console.log(typeof i); // string
                for (let s of bfs(str.slice(0, i) + str.slice(Number(i) + 1))) {
                    res.push(str[i] + s)
                }
            }
            return [...new Set(res)] //对'aaa...'这样的字符串进行去重
        }

        let str = 'abc'
        let res = bfs(str)
        console.log(res);
    </script>

2、深度优先搜索

<script>
        function fn(str) {
            let res = []
            let len = str.length
            dfs(str, '')

            function dfs(str, path) {
                if (path.length == len) {
                    res.push(path)
                }
                for (let i in str) {
                    dfs(str.slice(0, i) + str.slice(1 + Number(i)), path + str[i])
                }
            }
            return [...new Set(res)]
        }

        let str = 'aabc'
        let res = fn(str)
        console.log(res);
    </script>

三、查找

1、二分查找

<script>
        function search(nums, target) {
            nums.sort((a, b) => a - b)
            let left = 0
            let right = nums.length - 1

            while (left <= right) {
                let mid = Math.floor((left + right) / 2)
                if (nums[mid] == target) {
                    return mid
                } else if (nums[mid] > target) {
                    right = mid - 1
                } else {
                    left = mid + 1
                }
            }
            return -1
        }

        let nums = [4, 2, 6, 8, 20, 7, 1]
        console.log(search(nums, 20));
    </script>

2、找出出现次数最多的元素 

<script>
        function search(nums) {
            let map = new Map()
            nums.forEach(element => {
                if (map.has(element)) {
                    map.set(element, map.get(element) + 1)
                } else {
                    map.set(element, 1)
                }
            })
            console.log(map);

            let maxNum = 0
            let maxValue = []
            for (let i of map.keys()) { //map 与 for of 搭配,不用for in ,map.keys()表示遍历key, map.values()表示遍历value
                if (map.get(i) > maxNum) {
                    maxNum = map.get(i)
                    maxValue = [i]
                } else if (map.get(i) == maxNum) {
                    maxValue.push(i)
                }
            }
            //方法2
            /* map.forEach((element, value) => {
                //element为键值,value为键名
                if (element > maxNum) {
                    maxNum = element
                    maxValue = [value]
                } else if (element == maxNum) {
                    maxValue.push(value)
                }
            }) */

            return maxValue
        }

        let nums = [1, 1, 2, 2, 3, 4]
        let res = search(nums)
        console.log(res);
    </script>

四、动态规划

1、跳台阶

<script>
        function jump(n) {
            let res = [1, 1]
            for (let i = 2; i <= n; i++) {
                res.push(res[i - 1] + res[i - 2])
            }
            return res[n]
        }

        console.log(jump(8))
    </script>

2、斐波那契数列

<script>
        function fib(n) {
            let res = [0, 1]
            for (let i = 2; i <= n; i++) {
                res.push(res[i - 1] + res[i - 2])
            }
            return res[n]
        }

        console.log(fib(8))
    </script>

3、连续子数组的最大和

<script>
        function maxSub(nums) {
            if (nums.length <= 1) return nums
            let max = nums[0]
            let sum = nums[0]
            for (let i = 1; i < nums.length; i++) {
                sum = sum < 0 ? nums[i] : sum + nums[i]
                max = Math.max(sum, max)
            }
            return max
        }

        let nums = [-1, 2, 3, -2, 5]
        console.log(maxSub(nums));
    </script>

五、二叉树

1、二叉树最小深度

<script>
        function minDepth(root) {
            if (root == null) return 0
                //如果左子树等于空,我们返回右子树的最小高度+1
            if (root.left == null) return minDepth(root.right) + 1
                //如果右子树等于空,我们返回左子树的最小高度+1
            if (root.right == null) return minDepth(root.left) + 1
                //如果左右子树都不为空,我们返回左右子树深度最小的那个+1
            return Math.min(minDepth(root.left), minDepth(root.right)) + 1
        }

        class node {
            constructor(val, left, right) {
                this.val = val
                this.left = left
                this.right = right
            }
        }

        let root1 = new node(5, 6, null)
        let root2 = new node(3, root1, null)
        let root3 = new node(2, null, 4)
        let root = new node(1, root3, root2)

        console.log(minDepth(root));
    </script>

2、二叉树最大深度

 <script>
        function maxDepth(root) {
            if (root == null) return 0
                //如果左子树等于空,我们返回右子树的最小高度+1

            return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1
        }

        class node {
            constructor(val) {
                this.val = val
                this.left = null
                this.right = null
            }
        }

        let root6 = new node(6)
        let root5 = new node(5)
        root5.left = root6
        let root3 = new node(3)
        root3.left = root5
        let root4 = new node(4)
        let root2 = new node(2)
        root2.right = root4
        let root1 = new node(1)
        root1.left = root2
        root1.right = root3
        console.log(maxDepth(root1));
    </script>

3、二叉树的中序,前序,后序遍历

(1)前序遍历

<script>
        class node {
            constructor(val) {
                this.val = val
                this.left = null
                this.right = null
            }
        }

        let root6 = new node(6)
        let root5 = new node(5)
        root5.left = root6
        let root3 = new node(3)
        root3.left = root5
        let root4 = new node(4)
        let root2 = new node(2)
        root2.right = root4
        let root1 = new node(1)
        root1.left = root2
        root1.right = root3

        function preOrder(root) {
            if (root == null) return
            console.log(root.val);
            preOrder(root.left)
            preOrder(root.right)
        }

        preOrder(root1)
    </script>

(2)中序遍历

<script>
        function preOrder(root) {
            if (root == null) return
            preOrder(root.left)
            console.log(root.val);
            preOrder(root.right)
        }

        preOrder(root1)  
    </script>

(3)后序遍历

 function preOrder(root) {
            if (root == null) return
            preOrder(root.left)
            preOrder(root.right)
            console.log(root.val);
        }

4、另一棵树是否存在相同子树

<script>
        function isSub(root, subroot) {
            if (root == null) return false
                //1. root是自身的一颗子树和subRoot是相等的
                //2. 递归查找左子树有没有和subRoot一样的
                //3. 递归查找右子树有没有和subRoot一样的
            return testIsSub(root, subroot) || isSub(root.left, subroot) || isSub(root.right, subroot)
        }

        function testIsSub(root, subroot) {
            if (root == null && subroot == null) return true
            if (root == null || subroot == null) return false
            if (root.val != subroot.val) return false

            return testIsSub(root.left, subroot.left) && testIsSub(root.right, subroot.right)
        }

        class node {
            constructor(val) {
                this.val = val
                this.left = null
                this.right = null
            }
        }

        let root6 = new node(6)
        let root5 = new node(5)
        root5.left = root6
        let root3 = new node(3)
        root3.left = root5
        let root4 = new node(4)
        let root2 = new node(2)
        root2.right = root4
        let root1 = new node(1)
        root1.left = root2
        root1.right = root3

        let root4_2 = new node(4)
        let root = new node(2)
        root.right = root4_2

        console.log(isSub(root1, root));
    </script>

六、链表

1、合并两个有序列表

<script>
        class list {
            constructor(val, next) {
                this.val = val
                this.next = next ? next : null
            }
        }

        //1->3->5
        let list5 = new list(5)
        let list3 = new list(3, list5)
        let list1 = new list(1, list3)
            //2->4->6
        let list6 = new list(6)
        let list4 = new list(4, list6)
        let list2 = new list(2, list4)

        function mergelist(list1, list2) {
            let head = new list(-1)
            let node = head
            while (list1 && list2) {
                if (list1.val < list2.val) {
                    node.next = list1
                    list1 = list1.next
                } else {
                    node.next = list2
                    list2 = list2.next
                }
                node = node.next
            }

            node.next = list1 ? list1 : list2
            return head.next
        }

        console.log(mergelist(list1, list2));
    </script>

2、判断是否为环形链表

<script>
        class list {
            constructor(val, next) {
                this.val = val
                this.next = next ? next : null
            }
        }

        //1->3->->4->5
        let list5 = new list(5)
        let list4 = new list(4, list5)
        let list3 = new list(3, list4)
        let list1 = new list(1, list3)
        list5.next = list1

        function hasLoop(list) {
            let fast = list
            let slow = list

            while (fast != null && fast.next != null) {
                slow = slow.next
                fast = fast.next.next

                if (slow == fast) return true
            }
            return false
        }

        console.log(hasLoop(list1));
    </script>

3、是否为回文链表

<script>
        class list {
            constructor(val, next) {
                this.val = val
                this.next = next ? next : null
            }
        }

        //1->2->->2->1
        let list5 = new list(1)
        let list4 = new list(2, list5)
        let list3 = new list(2, list4)
        let list1 = new list(1, list3)

        function isPalindrome(list) {
            let temp = []
            while (list != null) {
                temp.push(list.val)
                list = list.next
            }
            let len = temp.length
            for (let i = 0; i < Math.floor((len - 1) / 2); i++) {
                if (temp[i] != temp[len - i - 1]) return false
            }
            return true
        }

        console.log(isPalindrome(list1));
    </script>

七、字符串

1.反转字符串

<script>
        function reverseString(str) {
            let newStr = str.split('').reverse().join('')
                //.join('*')把数组中的所有元素转换为一个字符串, 括号内为数组之间的添加符号
            return newStr
        }

        let s = reverseString('123654')
        console.log(s);
    </script>

2、最长公共前缀

<script>
        var longestCommonPrefix = function(strs) {
            if (strs.length == 0) return ''
            let str = strs[0]
            let l = strs[0].length
            let len = strs.length
            for (let i = 0; i < l; i++) {
                for (let j = 1; j < len; j++) {
                    if (strs[j].charAt(i) != str.charAt(i)) {
                        return str.substring(0, i)
                    }
                }
            }
            return str
        }

        let strs = ["flower", "flow", "flight"]
        console.log(longestCommonPrefix(strs));
    </script>

3、最长回文子串

<script>
        function longestPalindrome(s) {
            if (s.length == 0) return ''
            if (s.length == 1) return s
            let maxLen = 1
            let minLeft = 0

            for (let i = 0; i < s.length; i++) {
                let left = i - 1
                let right = i + 1
                let len = 1

                while (right < s.length && s.charAt(i) == s.charAt(right)) {
                    right++
                    len++
                }
                while (left >= 0 && right < s.length && s.charAt(left) == s.charAt(right)) {
                    left--
                    right++
                    len = len + 2
                }
                if (len > maxLen) {
                    minLeft = left + 1
                    maxLen = len
                }
            }
            return s.substring(minLeft, minLeft + maxLen)
        }

        let s = 'aabaccabdd'
        console.log(longestPalindrome(s));
    </script>

八、栈

1、基本计算器

<script>
        //给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
        /* 加号:将数字压入栈;
        减号:将数字的相反数压入栈;
        乘除号:计算数字与栈顶元素,并将栈顶元素替换为计算结果。 */
        var calculate = function(s) {
            s = s.trim()
            let stack = []
            let pre = '+' //初始符号
            let num = 0
            for (let i = 0; i < s.length; i++) {
                //isNaN 判断是否不为数字型,若不是返回true
                // Number() 函数把对象的值转换为数字, 如果对象的值无法转换为数字,那么 Number() 函数返回 NaN
                if (!isNaN(Number(s[i])) && s[i] != ' ') {
                    num = num * 10 + parseInt(s[i]) // *10是因为可能出现多位数
                }

                if (isNaN(Number(s[i])) || i == s.length - 1) {
                    switch (pre) {
                        case '+':
                            stack.push(num)
                            break
                        case '-':
                            stack.push(-num)
                            break
                        case '*':
                            stack.push(stack.pop() * num)
                            break
                        default:
                            stack.push(stack.pop() / num | 0)
                    }
                    num = 0
                    pre = s[i]
                }
            }
            return stack.reduce((a, b) => {
                return a + b
            })
        }

        console.log(calculate('4+5*6-3'));
    </script>

2、有效括号

<script>
        var isValid = function(s) {
            let stack = []
            let map = {
                '(': ')',
                '[': ']',
                '{': '}'
            }
            for (let i = 0; i < s.length; i++) {
                if (s.charAt(i) == map[stack[stack.length - 1]]) {
                    stack.pop()
                } else {
                    stack.push(s.charAt(i))
                }
            }
            if (stack.length == 0) return true
            return false
        }

        let s = "(]"
        console.log(isValid(s));
    </script>

九、滑动窗口

1、无重复字符的最长子串

var lengthOfLongestSubstring = function(s) {
    let len = 0
    let left = 0
    let map = new Map()
    for(let i=0; i < s.length; i++){
        if(map.has(s.charAt(i))){
            left = Math.max(left,map.get(s.charAt(i))+1)
        }
        map.set(s.charAt(i),i)
        len = Math.max(len, i-left+1)
    }
    return len
};

2、和为s的连续正序序列

 <script>
        var findContinuousSequence = function(target) {
            let left = 1
            let right = 1
            let res = []
            let sum = 0
            while (left < target / 2) {
                if (sum < target) {
                    sum += right
                    right++
                } else if (sum > target) {
                    sum -= left
                    left++
                } else {
                    let arr = []
                    for (let i = left; i < right; i++) {
                        arr.push(i)
                    }
                    res.push(arr)
                    sum -= left
                        ++left
                }
            }
            return res
        }

        let target = 9
        console.log(findContinuousSequence(target));
    </script>

3、和为k的子数组

<body>
    <script>
        //给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数
        var subarraySum = function(nums, k) {
            let map = new Map([
                    [0, 1]
                ]) //初始化 Map,可以以数组的格式来传入键值对
            let pre = 0
            let count = 0
            for (let i = 0; i < nums.length; i++) {
                pre += nums[i]
                if (map.has(pre - k)) {
                    count += map.get(pre - k)
                }
                map.set(pre, (map.get(pre) | 0) + 1)
            }
            return count
        }

        let arr = [1, 1, 1, 2]
        console.log(subarraySum(arr, 3));
    </script>
</body>

十、回溯

1、全排列

 <script>
        function permute(nums) {
            let len = nums.length
            let res = []
            dfs(nums, [])

            function dfs(nums, arr) {
                if (arr.length == len) {
                    res.push([...arr])
                    return
                }

                for (let i = 0; i < len; i++) {
                    if (arr.indexOf(nums[i]) != -1) continue
                    arr.push(nums[i])
                    dfs(nums, arr)
                    arr.pop()
                }
            }
            return res
        }

        console.log(permute(['a', 'b', 'c']));
    </script>

2、全排列||

<script>
        function permuteUnique(nums) {
            let len = nums.length
            let res = []
            let use = [] //判断是否使用过

            nums.sort((a, b) => {
                return a - b
            })
            dfs(nums, [])
            return res

            function dfs(nums, arr) {
                if (arr.length == len) {
                    res.push(arr.slice())
                    return
                }

                for (let i = 0; i < len; i++) {
                    if (use[i] || (i > 0 && nums[i] == nums[i - 1] && !use[i - 1])) continue
                    arr.push(nums[i])
                    use[i] = true
                    dfs(nums, arr)
                    use[i] = false
                    arr.pop()
                }
            }

        }

        console.log(permuteUnique([1, 1, 2]));
    </script>

3、组合

<script>
        //给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合
        function conbine(n, k) {
            let res = []
            dfs(1, [])
            return res

            function dfs(start, arr) {
                if (arr.length == k) {
                    res.push(arr.slice())
                    return
                }

                for (let i = start; i <= n; i++) {
                    arr.push(i)
                    dfs(i + 1, arr)
                    arr.pop()
                }
            }
        }

        console.log(conbine(4, 2));
    </script>

4、组合总和

 <!-- 给你一个 无重复元素 的整数数组 nums 和一个目标整数 target ,
    找出 nums 中可以使数字和为目标数 target 的 所有不同组合(数字可以重复) ,
    并以列表形式返回。你可以按 任意顺序 返回这些组合 -->
    <script>
        function combinationSum(nums, target) {
            nums.sort((a, b) => {
                return a - b
            })
            let res = []
            let len = nums.length

            dfs(0, target, [])
            return res

            function dfs(start, target, arr) {
                if (target == 0) {
                    res.push(arr.slice())
                    return
                }

                for (let i = start; i < len && target - nums[i] >= 0; i++) {
                    arr.push(nums[i])
                    dfs(i, target - nums[i], arr)
                    arr.pop()
                }
            }
        }

        console.log(combinationSum([2, 3, 6, 7], 7));
    </script>

十一、股票

1、买卖股票的最佳时机

<script>
        var maxProfit = function(prices) {
            let res = 0
            let pre = 0
            let len = prices.length

            for (let i = 1; i < len; i++) {
                let diff = prices[i] - prices[i - 1] //两天之间的利润差
                pre = Math.max(pre + diff, 0)
                res = Math.max(res, pre)
            }

            return res
        }

        console.log(maxProfit([7, 1, 5, 3, 6, 4]));
    </script>

2、买卖股票的最佳时机||

 <!--  给定一个数组 prices ,其中 prices[i] 表示股票第 i 天的价格。
在每一天,你可能会决定购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以购买它,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
prices = [7,1,5,3,6,4]  在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 
这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3
-->

    <script>
        var maxProfit = function(prices) {
            let res = 0
            for (let i = 1; i < prices.length; i++) {
                res += Math.max(0, prices[i] - prices[i - 1])
            }
            return res
        }

        console.log(maxProfit([7, 1, 5, 3, 6, 4]));
    </script>

3、买卖股票最佳时机含冷冻期

<script>
        //卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
        function maxProfit(price) {
            //hold[i] 表示第i天持有股票,有两种情况(1)前天卖了,今天买了(2)昨天买了,今天休息
            //unhold[i] 表示第i天未持有股票,有两种情况(1)昨天卖了,今天休息 (2)今天卖了
            let len = price.length
            let hold = new Array(len)
            let unhold = new Array(len)
            hold[0] = -price[0]
            unhold[0] = 0

            for (let i = 1; i < len; i++) {
                if (i == 1) {
                    hold[1] = Math.max(hold[0], -price[1])
                } else {
                    hold[i] = Math.max(hold[i - 1], unhold[i - 2] - price[i])
                }
                unhold[i] = Math.max(unhold[i - 1], hold[i - 1] + price[i])
            }
            return unhold[len - 1]
        }

        console.log(maxProfit([1, 2, 3, 0, 2]));
    </script>

十二、数组

1、两数之和

<script>
        /* 给定一个整数数组 nums 和一个整数目标值 target,
                        请你在该数组中找出 和为目标值 target  的那两个整数,
                        并返回它们的数组下标。 */

        function twoSum(nums, target) {
            let map = new Map()
            for (let i = 0; i < nums.length; i++) {
                if (map.has(target - nums[i])) {
                    return [map.get(target - nums[i]), i]
                }
                map.set(nums[i], i)
            }
            return []
        }

        console.log(twoSum([2, 7, 11, 15], 9));
    </script>

2、移动零

<script>
        //给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
        var moveZero = function(nums) {
            let j = 0
            for (let i = 0; i < nums.length; i++) {
                if (nums[i] != 0) {
                    let temp = nums[i]
                    nums[i] = nums[j]
                    nums[j] = temp
                    j++
                }
            }
            return nums
        }

        console.log(moveZero([0, 1, 0, 3, 12]));
    </script>

3、数组形式的整数加法

<script>
        /* 对于 num = 1321 ,数组形式是 [1,3,2,1] 。
                        给定 num, 整数的 数组形式, 和整数 k, 返回 整数 num + k 的 数组形式。 */
        var addToArrayForm = function(num, k) {
            const res = [];
            const n = num.length;
            for (let i = n - 1; i >= 0; --i) {
                let sum = num[i] + k % 10;
                k = Math.floor(k / 10);
                if (sum >= 10) {
                    k++;
                    sum -= 10;
                }
                res.push(sum);
            }
            for (; k > 0; k = Math.floor(k / 10)) {
                res.push(k % 10);
            }
            res.reverse();
            return res;
        }

        console.log(addToArrayForm([1, 2, 0, 0], 34));
    </script>

4、公平的糖果交换

<script>
        var fairCandySwap = function(aliceSizes, bobSizes) {
            let sumA = aliceSizes.reduce((total, cur) => {
                return total + cur
            })
            let sumB = bobSizes.reduce((total, cur) => {
                return total + cur
            })

            let set = new Set(aliceSizes)
            for (let b of bobSizes) {
                let a = b + Math.floor((sumA - sumB) / 2) // sumA - a + b = sumB - b + a
                if (set.has(a)) return [a, b]
            }
            return []
        }

        console.log(fairCandySwap([1, 1], [2, 2]));
    </script>

5、 合并两个有序数组

 <script>
        /* 给你两个按 非递减顺序 排列的整数数组  nums1 和 nums2, 另有两个整数 m 和 n,
                                分别表示 nums1 和 nums2 中的元素数目。
                                请你 合并 nums2 到 nums1 中, 使合并后的数组同样按 非递减顺序 排列。 */

        var merge = function(nums1, m, nums2, n) {
            let p1 = 0,
                p2 = 0;
            const sorted = new Array(m + n).fill(0);
            var cur;
            while (p1 < m || p2 < n) {
                if (p1 === m) {
                    cur = nums2[p2++];
                } else if (p2 === n) {
                    cur = nums1[p1++];
                } else if (nums1[p1] < nums2[p2]) {
                    cur = nums1[p1++];
                } else {
                    cur = nums2[p2++];
                }
                sorted[p1 + p2 - 1] = cur;
            }
            for (let i = 0; i != m + n; ++i) {
                nums1[i] = sorted[i];
            }
            return nums1
        };

        console.log(merge([1, 2, 3, 0, 0, 0], 3, [2, 5, 6], 3));
    </script>

6、只出现一次的数字

<script>
        function singleNumber(nums) {
            let signal = 0
            for (let num of nums) {
                //异或运算
                //一个数和0异或等于它本身,和自己异或等于0
                signal ^= num
            }
            return signal
        }

        console.log(singleNumber([2, 2, 1]));
    </script>

7、子数组最大平均数 I

<script>
        var findMaxAverage = function(nums, k) {
            let sum = 0
            let n = nums.length
            for (let i = 0; i < k; i++) {
                sum += nums[i]
            }
            let maxSum = sum
            for (let i = k; i < n; i++) {
                sum = sum + nums[i] - nums[i - k]
                maxSum = Math.max(maxSum, sum)
            }
            return maxSum / k
        }

        console.log(findMaxAverage([1, 12, -5, -6, 50, 3], 4));
    </script>

十三、阶乘后的零

 <script>
        //方法1
        /* var trailingZeroes = function(n) {
            let ans = 0;
            for (let i = 5; i <= n; i += 5) {
                for (let x = i; x % 5 == 0; x /= 5) {
                    ++ans;
                }
            }
            return ans;
        }; */

        //方法2
        var trailingZeroes = function(n) {
            let res = 0
            while (n != 0) {
                n = Math.floor(n / 5)
                res += n
            }
            return res
        };
    </script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值