前言
本文隶属于专栏《LeetCode 刷题汇总》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!
本专栏目录结构请见LeetCode 刷题汇总
Github 配套工程
正文
幕布
131. 分割回文串
回溯
package com.shockang.study.algorithm.java.leetcode.leetcode101_200.leetcode131.solution1;
import java.util.ArrayList;
import java.util.List;
/**
* 回溯
*
* @author Shockang
*/
public class Solution {
public List<List<String>> partition(String s) {
List<List<String>> res = new ArrayList<>();
List<String> list = new ArrayList<>();
dfs(s, 0, list, res);
return res;
}
public void dfs(String s, int pos, List<String> list, List<List<String>> res) {
if (pos == s.length()) res.add(new ArrayList<>(list));
else {
for (int i = pos; i < s.length(); i++) {
if (isPal(s, pos, i)) {
list.add(s.substring(pos, i + 1));
dfs(s, i + 1, list, res);
list.remove(list.size() - 1);
}
}
}
}
public boolean isPal(String s, int low, int high) {
while (low < high) if (s.charAt(low++) != s.charAt(high--)) return false;
return true;
}
}
132. 分割回文串 II
Java Version, with comments and better naming. Easier to understand
动态规划
package com.shockang.study.algorithm.java.leetcode.leetcode101_200.leetcode132.solution1;
import java.util.stream.IntStream;
/**
* @author Shockang
*/
public class Solution {
public int minCut(String s) {
// validate input
if (s == null || s.length() <= 1) {
return 0;
}
// dp
int N = s.length();
int[] dp = IntStream.range(0, N).toArray(); // initial value: dp[i] = i
for (int mid = 1; mid < N; mid++) { // iterate through all chars as mid point of palindrome
// CASE 1. odd len: center is at index mid, expand on both sides
for (int start = mid, end = mid; start >= 0 && end < N && s.charAt(start) == s.charAt(end); start--, end++) {
int newCutAtEnd = (start == 0) ? 0 : dp[start - 1] + 1;
dp[end] = Math.min(dp[end], newCutAtEnd);
}
// CASE 2: even len: center is between [mid-1,mid], expand on both sides
for (int start = mid - 1, end = mid; start >= 0 && end < N && s.charAt(start) == s.charAt(end); start--, end++) {
int newCutAtEnd = (start == 0) ? 0 : dp[start - 1] + 1;
dp[end] = Math.min(dp[end], newCutAtEnd);
}
}
return dp[N - 1];
}
}
133. 克隆图
Map+DFS
package com.shockang.study.algorithm.java.leetcode.leetcode101_200.leetcode133.solution1;
import com.shockang.study.algorithm.java.leetcode.common.graph.Node;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author Shockang
*/
public class Solution {
private Map<Integer, Node> map = new HashMap<>();
public Node cloneGraph(Node node) {
if (node == null)
return null;
if (map.containsKey(node.val))
return map.get(node.val);
Node res = new Node(node.val);
map.put(res.val, res);
res.neighbors.addAll(node.neighbors.stream().map(this::cloneGraph).collect(Collectors.toList()));
return res;
}
}
HashMap,LinkedList,BFS
package com.shockang.study.algorithm.java.leetcode.leetcode101_200.leetcode133.solution2;
import com.shockang.study.algorithm.java.leetcode.common.graph.Node;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
/**
* @author Shockang
*/
public class Solution {
public Node cloneGraph(Node node) {
if (node == null) {
return node;
}
HashMap<Node, Node> visited = new HashMap<>();
// 将题目给定的节点添加到队列
LinkedList<Node> queue = new LinkedList<>();
queue.add(node);
// 克隆第一个节点并存储到哈希表中
visited.put(node, new Node(node.val, new ArrayList()));
// 广度优先搜索
while (!queue.isEmpty()) {
// 取出队列的头节点
Node n = queue.remove();
// 遍历该节点的邻居
for (Node neighbor : n.neighbors) {
if (!visited.containsKey(neighbor)) {
// 如果没有被访问过,就克隆并存储在哈希表中
visited.put(neighbor, new Node(neighbor.val, new ArrayList()));
// 将邻居节点加入队列中
queue.add(neighbor);
}
// 更新当前节点的邻居列表
visited.get(n).neighbors.add(visited.get(neighbor));
}
}
return visited.get(node);
}
}
134. 加油站
sumGas,sumCost,start,tank
package com.shockang.study.algorithm.java.leetcode.leetcode101_200.leetcode134.solution1;
/**
* @author Shockang
*/
public class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int sumGas = 0;
int sumCost = 0;
int start = 0;
int tank = 0;
for (int i = 0; i < gas.length; i++) {
sumGas += gas[i];
sumCost += cost[i];
tank += gas[i] - cost[i];
if (tank < 0) {
start = i + 1;
tank = 0;
}
}
if (sumGas < sumCost) {
return -1;
} else {
return start;
}
}
}
135. 分发糖果
动态规划,初始都为 1,左一遍,右一遍
package com.shockang.study.algorithm.java.leetcode.leetcode101_200.leetcode135.solution1;
import java.util.Arrays;
/**
* 动态规划,初始都为 1,左一遍,右一遍
*
* @author Shockang
*/
public class Solution {
public int candy(int[] ratings) {
int n = ratings.length;
int[] candies = new int[n];
Arrays.fill(candies, 1);
for (int i = 1; i < n; i++) {
if (ratings[i] > ratings[i - 1]) {
candies[i] = candies[i - 1] + 1;
}
}
int sum = candies[n - 1];
for (int i = n - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1]) {
candies[i] = Math.max(candies[i], candies[i + 1] + 1);
}
sum += candies[i];
}
return sum;
}
}