332.重新安排行程
给定一个机票的字符串二维数组 [from, to],子数组中的两个成员分别表示飞机出发和降落的机场地点,对该行程进行重新规划排序。所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。
- 如果存在多种有效的行程,请你按字符自然排序返回最小的行程组合。例如,行程 ["JFK", "LGA"] 与 ["JFK", "LGB"] 相比就更小,排序更靠前
- 所有的机场都用三个大写字母表示(机场代码)。
- 假定所有机票至少存在一种合理的行程。
- 所有的机票必须都用一次 且 只能用一次。
示例 1:
- 输入:[["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]
- 输出:["JFK", "MUC", "LHR", "SFO", "SJC"]
示例 2:
- 输入:[["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
- 输出:["JFK","ATL","JFK","SFO","ATL","SFO"]
- 解释:另一种有效的行程是 ["JFK","SFO","ATL","JFK","ATL","SFO"]。但是它自然排序更大更靠后。
解题思路
映射问题
- 使用过的机票要进行处理,防止使用过的机票被再次使用甚至是死循环的出现。
- 因为机票可能有多张(可以从a飞到b多次),且每张机票只能用一次,所以需要将这些可能重复的机票记录下来,可以通过
Map<String, Map<String, Integer>>
来记录,第一个String存储出发地,第二个String存储目的地,Integer存储剩余次数。 - 在一开始需要对这个HashMap初始化,且因为需要按照排序选出最前面的,不能简单的使用HashMap,要用
TreeMap<String, Integer>()
这个数据结构,这是一个升序map,里面的元素按照String的字典顺序排序
回溯问题
- 用res记录最终的机场遍历顺序,通过取出res的最后一个元素来确定当前的出发地,到map中去寻找可以前往的目的地
Map.Entry<String, Integer> target : map.get(last).entrySet()
,可以前往则进入下一个地方,不能则遍历到无地方可去为止返回false。 - 当
res.size() == tickets.size() + 1
时遍历结束,返回res作为最终答案。这是回溯的返回条件。 - 本题回溯需要用boolean,我们需要返回值来判定结果是否是合法的,我们只需要找到一个行程,就是在树形结构中唯一的一条通向叶子节点的路线
51. N皇后
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
解题思路
- 回溯法:在每行找到一个正确的位置放下皇后之后就可以进入下一层,如果放不下则返回。因此此处的回溯也应该是boolean类型,需要后面的返回值来判定该方案可不可行。同时需要将所有位置都走一遍,因为要找出在n情况下所有皇后的放置情况,可能不止一种
- 本题通过
char[][]
[][]数组来记录皇后的放置情况有助于后续值的修改,因此在存入List<List<String>>
的结果时要进行数据结构的转换,字符数组转字符串可以采用String.copyValueOf(c)
或者new String(c)
- 在判定是否可以放置在该位置时,要从三个方向判断,分别是往上、左45度向上和右45度向上
37. 解数独
编写一个程序,通过填充空格来解决数独问题。
一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 空白格用 '.' 表示。
解题思路
- 对每个位置依次进行判定直到所有的格子都填了数字为止,当情况错误时则需要返回修正,因此也是一个boolean类型的回溯。当遇到本身就填有数字的情况要直接进入下一个状态,不要对当前格子进行修改。
- 在判定合法的时候行列都很好判断,在判定九宫格时需要一点小技巧:通过(row / 3) * 3和(column / 3 )* 3来判定当前位置所处的九宫格的起点(左上角位置)