• 算法复习之 暴力求解法


    暴力求解法

    简单枚举
    1. 给定一个整数n,按从小到大的顺序输出所有形如abcde / fghij = n的表达式,其中a ~ j 恰好为数字0 ~ 9 的一个全排列,可以有前导零。
      • 问题分析:我们没有必要去枚举所有0~9的全排列,而只需要枚举fghij,然后计算出abcde对应的数字,判断是否是0 ~ 9的全排列即可。
    public static boolean isOk(int i, int n) {
        boolean[] flag = new boolean[10];
        Arrays.fill(flag, false);
        int num = i;
        int count = 0;
        while(num > 0) {
            int temp = num % 10;
            if(!flag[temp]) {
                flag[temp] = true;
                count ++;
            }
            else return false;
            num /= 10;
        }
        num = i * n;
        while(num > 0) {
            int temp = num % 10;
            if(!flag[temp]) {
                flag[temp] = true;
                count ++;
            } else return false;
            num /= 10;
        }
        if(count == 10 || (count == 9 && !flag[0])) return true;
        return false;
    }
    
    public static List<String> division(int n) {
        List<String> ans = new ArrayList<>();
        for(int i = 0; i * n < 98766; i ++) {
            if(isOk(i, n)) {
                StringBuilder sb = new StringBuilder();
                sb.append(i * n);
                sb.append('/');
                sb.append(i);
                ans.add(sb.toString());
            }
        }
        return ans;
    }
    
    生成全排列
    • 给定一个整数n,生成1 ~ n的全排列。很容易想到可以通过递归实现。以1开头的全排列的特点是,第一位是1,后面n - 1位是2 ~ n 的全排列,依次类推。因此我们需要保证在寻找2 ~ n的全排列的时候,确保1不会被选到,这就需要一个临时数组去存储已经被排列到的值。那么每次递归我们就顺序去查找1 ~ n的值,没被选到的第一个值就可以加入到全排列中,然后继续递归进行选取。由于我们每次递归都是从1 ~ n的顺序去选的,以2 ~ 4为例,我们会在生成2到4全排列的时候,第二个数依次选择2,3,4。第二个数确定的情况下去寻找第三个数,也会按顺序从1 ~ n依次选取没有出现在临时数组中的数,这就确保了可以按照顺序生成全排列了。
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    public class GetPermutation {
    
        public static void getPermutation(List<List<Integer>> list, int n, int[] arr, int cur) {
            if(n == cur) {
                List<Integer> temp = new ArrayList<>();
                for(int i = 0; i < cur; i ++) {
                    temp.add(arr[i]);
                }
                list.add(temp);
                return;
            } else for(int i = 1; i <= n; i ++) {
                boolean flag = true;
                for(int j = 0; j < cur; j ++) {
                    if(arr[j] == i) flag = false;
                }
                if(flag) {
                    arr[cur] = i;
                    getPermutation(list, n, arr, cur + 1);
                }
            }
        }
    
        public static void main(String[] args) {
            int n = 4;
            int[] arr = new int[n];
            List<List<Integer>> list = new ArrayList<>(n);
            getPermutation(list, n, arr, 0);
            System.out.println(list);
        }
    
    }
    
    子集生成
    • 给定一个集合,枚举所有可能的子集。
      二进制法:对于数组中有4个数字的情况,我们可以使用四个二进制位表示是否选取对应位置的数字,这些二进制组合对应于10进制中的0 ~ 15(其中0表示全都不选,15表示全选)。对于这16种情况,遍历即可得到所有数字选与不选的情况,当然,我们得到的只是数组中的下标的选取情况。
    public static void print(int n, int s) {
        for(int i = 0; i < n; i ++) {
            if((s & (1 << i)) > 0) { // 判断数字s二进制位上的每一位是否为1
                System.out.print(i + " ");
            }
        }
        System.out.println();
    }
    
    public static void main(String[] args) {
        int n = 3;
        for(int i = 1; i < (1 << n); i ++) {
            print(n, i);
        }
    }
    
    时间并不会因为你的迷茫和迟疑而停留,就在你看这篇文章的同时,不知道有多少人在冥思苦想,在为算法废寝忘食,不知道有多少人在狂热地拍着代码,不知道又有多少提交一遍又一遍地刷新着OJ的status页面…… 没有谁生来就是神牛,而千里之行,始于足下!
  • 相关阅读:
    HDU1548:A strange lift
    hdu1978_How many ways dfs+记忆化搜索
    HDU1518:Square(DFS)
    HDU ACM 1495 非常可乐(广搜BFS)
    HDU1372:Knight Moves(BFS)
    662_二叉树最大宽度
    590_N叉树的后序遍历
    一直在坚持
    动态链接库DLL的操作顺序
    最近木马的查杀方法/各类杀毒软件的使用
  • 原文地址:https://www.cnblogs.com/bianjunting/p/14678688.html
Copyright © 2020-2023  润新知