• 从一个无序,不相等的数组中,选取N个数,使其和为M实现算法


    // 递归分解,最后转换成求2数之和
    //  一个方法从 2Sum 秒杀到 100Sum
    //  https://leetcode-cn.com/problems/3sum/solution/yi-ge-fang-fa-tuan-mie-by-labuladong/
    
    var nSumTarget = function (nums, n, start, target) {
        let res = []
        if (n < 2 || n > nums.length) {
            return res
        }
        if (n == 2) {
            let low = start;
            let high = nums.length - 1;
            while (low < high) {
                let sum = nums[low] + nums[high];
                let left = nums[low]
                let right = nums[high]
                if (sum < target) {
                    while (low < high && nums[low] === left) {
                        low++
                    }
                } else if (sum > target) {
                    while (low < high && nums[high] === right) {
                        high--
                    }
                } else {
                    res.push([left, right])
                    while (low < high && nums[low] === left) {
                        low++
                    }
                    while (low < high && nums[high] === right) {
                        high--
                    }
                }
            }
        } else {
            for (let i = start; i < nums.length; i++) {
                let sub = nSumTarget(nums, n - 1, i + 1, target - nums[i])
                for (let arr of sub) {
                    arr.push(nums[i])
                    res.push(arr)
                }
                while (i < nums.length && nums[i] === nums[i + 1]) {
                    i++
                }
            }
        }
        return res
    }
    var findGroup = function (nums, n, sum) {
        nums = nums.sort((a, b) => a - b)
        return nSumTarget(nums, n, 0, sum)
    };
    
    // 位运算
    // https://blog.csdn.net/weixin_34130269/article/details/91382220
    const search = (arr, count, sum) => {
        // 计算某选择情况下有几个 `1`,也就是选择元素的个数
        const n = num => {
            let count = 0
            while (num) {
                num &= (num - 1)
                count++
            }
            return count
        }
    
        let len = arr.length, bit = 1 << len, res = []
    
        // 遍历所有的选择情况
        for (let i = 1; i < bit; i++) {
            // 满足选择的元素个数 === count
            if (n(i) === count) {
                let s = 0, temp = []
    
                // 每一种满足个数为 N 的选择情况下,继续判断是否满足 和为 M
                for (let j = 0; j < len; j++) {
                    // 建立映射,找出选择位上的元素
                    if ((i & 1 << j) !== 0) {
                        s += arr[j]
                        temp.push(arr[j])
    
                        // 左移,从右边的index往左边看
                       // s += arr[len -1 - j]
                       // temp.push(arr[len -1 - j])
                    }
                }
    
                // 如果这种选择情况满足和为 M
                if (s === sum) {
                    res.push(temp)
                }
            }
        }
    
        return res
    }
    
    // 0,1背包问题
    function find(arr, n, sum) {
        let res = []
        findGroup(arr, n, sum, [])
        function findGroup(arr, n, sum, oneRes) {
            if (n > arr.length) return false
            if (sum == 0 && n == 0) {
                res.push(oneRes)
                return true;
            } else if (n <= 0) {
                return false;
            }
            if (n > 0) {
                let temp = arr.slice(1, arr.length)
                findGroup(temp, n - 1, sum - arr[0], [...oneRes,arr[0]])
                findGroup(temp, n, sum, [...oneRes])
            }
        }
        return res
    }
    
    // 如果只要判断能不能找到
    function findGroup(arr, n, sum) {
        if (n > arr.length) return false
        if (sum == 0 && n == 0) {
            return true;
        } else if (n <= 0) {
            return false;
        }
        if (n > 0) {
            // if (arr.length === 0) return false
            let temp = arr.slice(1, arr.length)
            return findGroup(temp, n - 1, sum - arr[0]) || findGroup(temp, n, sum)
        }
    }
    

    参考资料:
    https://wizardforcel.gitbooks.io/the-art-of-programming-by-july/content/02.03.html

    https://blog.csdn.net/MrZZhou/article/details/77860278

  • 相关阅读:
    LinUI学习1 框架的引入
    LinUI学习2 config配置文件配置和使用
    LinUI学习3 Http请求封装与使用
    【网络编程】学习笔记02 套接字类型与协议设置
    【系统编程】 守护进程
    【网络编程】学习笔记03 地址族与数据序列
    【网络编程】学习笔记01 套接字与文件操作
    【系统编程】 进程间通信方式
    【网络编程】学习笔记06 I/O多路复用之epoll
    【网络编程】学习笔记04 server端和client代码
  • 原文地址:https://www.cnblogs.com/fazero/p/13715888.html
Copyright © 2020-2023  润新知