回溯day6

2022/4/22 23:19:24

本文主要是介绍回溯day6,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

51. N 皇后

class Solution {
    private List<List<String>> res;
    //存第i行放置位置
    private int[] place;
    public List<List<String>> solveNQueens(int n) {
        res = new ArrayList<>();
        place = new int[n];
        //i代表行
        backtracking(n, 0);
        return res;
    }
    private void backtracking(int n, int i) {
        //放满存可行解
        if (i >= n) {
            char[][] cc = new char[n][n];
            for (char[] c : cc) {
                Arrays.fill(c, '.');
            }
            for (int k = 0; k < n; k++) {
                cc[k][place[k]] = 'Q';
            }
            List<String> list = new ArrayList<>();
            for (char[] c : cc) {
                list.add(new String(c));
            }
            res.add(list);
        }
        //试探该行是否存在可放置的列
        for (int j = 0; j < n; j++) {
            if (placeQueen(i, j)) {
                place[i] = j;
                backtracking(n, i + 1);
                //隐藏回溯 后续会覆盖
            }
        }
    }
    //x:行 y:列
    private boolean placeQueen(int x, int y) {
        //第一行总是可以放的
        if (x == 0) return true;
        //该位置和前面行是否冲突
        for (int i = 0; i < x; i++) {
            //在同一列上或对角线上 冲突 返回false
            if (y == place[i] || Math.abs(x - i) == Math.abs(y - place[i]))
                return false;
        }
        return true;
    }
}

332. 重新安排行程

class Solution {
    //此题关键在于容器的选择和使用上
    private Map<String, Map<String, Integer>> map;
    private LinkedList<String> res;
    public List<String> findItinerary(List<List<String>> tickets) {
        res = new LinkedList<>();
        map  = new HashMap<>();
        //将List<List<String>> 转化成Map<String, Map<String, Integer>>
        //Map<String, Integer>存同一个起点的可达终点以及同一起点目的地机票出现的次数,要保证每张机票都用到
        Map<String, Integer> temp;
        for (List<String> list : tickets) {
            if (map.containsKey(list.get(0))) {
                temp = map.get(list.get(0));
                temp.put(list.get(1), temp.getOrDefault(list.get(1), 0) + 1);
            } else {
                //使用TreeMap排序 默认升序 优先处理在字典中排前面的
                temp = new TreeMap();
                temp.put(list.get(1), 1);
            }
            map.put(list.get(0), temp);
        }
        res.add("JFK");
        backtracking(tickets.size());
        return new ArrayList<>(res);
    }

    private boolean backtracking(int size) {
        //机票数+1就是机场数 使用boolean可以让父调用接受并直接返回 前面使用TreeSet排序过,找到的一个结果就是最优的
        if (size + 1 == res.size()) {
            return true;
        }
        String des = res.getLast();
        if (map.containsKey(des)) {
            //所有可以走的路径都走一下
            for (Map.Entry<String, Integer> path : map.get(des).entrySet()) {
                int count = path.getValue();
                if (count > 0) {
                    res.add(path.getKey());
                    path.setValue(count - 1);
                    if (backtracking(size)) return true;
                    //回溯
                    res.removeLast();
                    path.setValue(count);
                } //if
            } //for
        }//if
        return false;
    }
}

 

 

参考:programmercarl.com



这篇关于回溯day6的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程