题解 | #火车进站#相比递归更喜欢循环+面向对象的写法

火车进站

https://www.nowcoder.com/practice/97ba57c35e9f4749826dc3befaeae109

import java.util.*;
import java.util.stream.*;
import java.util.regex.*;
import java.util.function.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        int count = in.nextInt();
        LinkedList<String> queue = new LinkedList<>();
        while (count > 0 ) {
            queue.add(in.next());
            count--;
        }

        /**
        分别使用递归和循环的方法:循环实现更难,从递归转换而来
         */
        // System.out.println(String.join("\n", trainRecursion(queue)));
        System.out.println(String.join("\n", trainIteration(queue)));
    }

    static List<String> trainIteration(LinkedList<String> queue) {
        // 模拟递归
        List<List<String>> allPlans = new ArrayList<>();
        // 定义调度中的对象
        List<Progress> progresses = new ArrayList<>();
        progresses.add(new Progress(queue));

        // 还有未完成的调度
        while (progresses.size() > 0) {
            // 对每个调度进行操作
            List<Progress> newProgresses = new ArrayList<>();
            for (int i = 0 ; i < progresses.size(); i++) {
                Progress p = progresses.get(i);
                if (p.finished()) {
                    allPlans.add(p.getResult());
                } else {
                    newProgresses.addAll(p.moreProgress());
                }
            }
            progresses = newProgresses;
        }
        return allPlans.stream().map(l-> {
            return String.join(" ", l);
        }).distinct().sorted().collect(Collectors.toList());
    }

    /**
    火车站视角来思考:两种情况都要“走”到(模拟“走”完所有可能的方案)
        - 一次调度是指,让一辆车进站或者让一辆车出站
        - 调度完毕是指:当前的 N 辆车均完成了进出站
    */
    static List<String> trainRecursion(LinkedList<String> queue) {
        List<List<String>> allPlans = new ArrayList<>();
        recursion(queue, new LinkedList<String>(), new ArrayList<String>(), allPlans);

        return allPlans.stream().map(l-> {
            return String.join(" ", l);
        }).distinct().sorted().collect(Collectors.toList());
    }

    static void recursion(LinkedList<String> queue, LinkedList<String> stack,
                          List<String> plan, List<List<String>> allPlans) {
        if (queue.isEmpty() && stack.isEmpty()) {
            allPlans.add(plan);
            return;
        }
        // 1 进站
        if (!queue.isEmpty()) {
            // clone queue and stack
            LinkedList<String> q = new LinkedList<>(queue);
            LinkedList<String> s = new LinkedList<>(stack);
            List<String> p = new ArrayList<>(plan);
            s.push(q.poll());
            recursion(q, s, p, allPlans);
        }
        // 2 出站
        if (!stack.isEmpty()) {
            // clone queue and stack
            LinkedList<String> q = new LinkedList<>(queue);
            LinkedList<String> s = new LinkedList<>(stack);
            List<String> p = new ArrayList<>(plan);
            p.add(s.pop());
            recursion(q, s, p, allPlans);
        }
    }
}

class Progress {
    LinkedList<String> queue = new LinkedList<>();
    LinkedList<String> stack = new LinkedList<>();
    List<String> result = new ArrayList<>();

    Progress(LinkedList<String> queue) {
        this.queue = queue;
    }

    Progress(LinkedList<String> queue, LinkedList<String> stack,
             List<String> result) {
        this.queue = queue;
        this.stack = stack;
        this.result = result;
    }

    public boolean finished() {
        return queue.isEmpty() && stack.isEmpty();
    }

    public List<String> getResult() {
        return this.result;
    }

    public List<Progress> moreProgress() {
        List<Progress> list = new ArrayList<>();
        if (this.finished()) return null;

        if (!queue.isEmpty()) {
            // clone
            LinkedList<String> q = new LinkedList<>(queue);
            LinkedList<String> s = new LinkedList<>(stack);
            List<String> r = new ArrayList<>(result);
            s.push(q.poll());
            list.add(new Progress(q, s, r));
        }
        if (!stack.isEmpty()) {
            // clone
            LinkedList<String> q = new LinkedList<>(queue);
            LinkedList<String> s = new LinkedList<>(stack);
            List<String> r = new ArrayList<>(result);
            r.add(s.pop());
            list.add(new Progress(q, s, r));
        }
        return list;
    }
}


全部评论

相关推荐

04-03 12:09
東京大学 C++
点赞 评论 收藏
分享
工科女的日常:真诚建议:别再用这种花哨的模板,可以看看我发的那个零经验找实习发帖子
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务