链表
lc14 环形链表 原题链接 难度:简单
通过set判断链表是否有环
括号和表达式相关
lc20 有效的括号 原题链接 难度:简单
使用栈处理,先入栈一个占位符?
,然后遇到左括号入栈,遇到右括号出栈,并判断出栈的左括号和此时的右括号是不是同一类的。
Java版本参考代码
class Solution {
public boolean isValid(String s) {
HashMap<Character, Character> map = new HashMap<>();
map.put('(', ')');
map.put('[', ']');
map.put('{', '}');
map.put('?', '?');
if (s.length() > 0 && !map.containsKey(s.charAt(0))) {
// 说明以右括号开头,不合法的括号序列
return false;
}
Deque<Character> stack = new LinkedList<>();
stack.push('?');
for (int i = 0; i < s.length(); i++) {
Character cur = s.charAt(i);
if (map.containsKey(cur)) {
// 遇到左括号,入栈
stack.push(cur);
} else {
// 当前字符是右括号
char top = stack.pop();
if (map.get(top) != cur) {
return false;
}
}
}
return stack.size() == 1;
}
}
图论
lc785 判断二分图 原题链接 难度:中等
Java版本参考代码
class Solution {
private int V;
private int[] colors;
private boolean[] visited;
private int[][] graph;
public boolean isBipartite(int[][] graph) {
this.graph = graph;
this.V = graph.length;
this.colors = new int[V];
this.visited = new boolean[V];
for (int v = 0; v < V; v++) {
if (!visited[v]) {
if (!dfs(v, 0)) {
return false;
}
}
}
return true;
}
private boolean dfs(int v, int color) {
visited[v] = true;
colors[v] = color;
for (int w : graph[v]) {
if (!visited[w]) {
// 如果没有访问过,则染另外一种颜色
if (!dfs(w, 1 - color)) return false;
} else {
// 如果访问过,且颜色和当前节点v的颜色相同,则说明这个图不是二分图。
if (colors[w] == colors[v]) {
return false;
}
}
}
return true;
}
}
lc695 岛屿的最大面积 原题链接 难度:中等
方法一:自己建图
// Java版本参考代码
class Solution {
private int R, C;
private int[][] grid;
private HashSet<Integer>[] G; // 建图,图的领接表表示
private int[][] dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
private boolean[] visited;
public int maxAreaOfIsland(int[][] grid) {
if (grid == null) return 0;
R = grid.length;
if (R == 0) return 0;
C = grid[0].length;
if (C == 0) return 0;
this.grid = grid;
// 建图
G = constructGraph();
int res = 0;
this.visited = new boolean[G.length];
// 求连通分量的最大节点数
for (int v = 0; v < G.length; v++) {
int x = v / C, y = v % C;
if (!visited[v] && grid[x][y] == 1) {
res = Math.max(res, dfs(v));
}
}
return res;
}
private HashSet<Integer>[] constructGraph() {
HashSet<Integer>[] g = new HashSet[R * C];
for (int i = 0; i < g.length; i++) {
g[i] = new HashSet<>();
}
for (int v = 0; v < g.length; v++) {
int x = v / C, y = v % C;
if (grid[x][y] == 1) {
for (int d = 0; d < 4; d++) {
int nextx = x + dirs[d][0];
int nexty = y + dirs[d][1];
if (inArea(nextx, nexty) && grid[nextx][nexty] == 1) {
int next = nextx * C + nexty;
g[v].add(next);
g[next].add(v);
}
}
}
}
return g;
}
private int dfs(int v) {
visited[v] = true;
// 顶点v所在的连通分量的节点数目
int res = 1;
for (int w : G[v]) {
if (!visited[w]) {
res += dfs(w);
}
}
return res;
}
boolean inArea(int x, int y) {
return x >= 0 && x < R && y >= 0 && y < C;
}
}
方法2:利用题目自身的数据结构,不自己建图,通过题目提供的数据结构去求得邻接关系。
// Java 参考代码
class Solution {
private int R, C;
private int[][] grid;
private int[][] dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
private boolean[][] visited;
public int maxAreaOfIsland(int[][] grid) {
if (grid == null) return 0;
R = grid.length;
if (R == 0) return 0;
C = grid[0].length;
if (C == 0) return 0;
this.grid = grid;
int res = 0;
this.visited = new boolean[R][C];
// 求连通分量的最大节点数
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (!visited[i][j] && grid[i][j] == 1) {
res = Math.max(res, dfs(i, j));
}
}
}
return res;
}
private int dfs(int x, int y) {
visited[x][y] = true;
// 顶点v所在的连通分量的节点数目
int res = 1;
// 对四个方向找邻接点
for (int d = 0; d < 4; d++) {
int nextx = x + dirs[d][0];
int nexty = y + dirs[d][1];
if (inArea(nextx, nexty) && grid[nextx][nexty] == 1) {
if (!visited[nextx][nexty]) {
res += dfs(nextx, nexty);
}
}
}
return res;
}
boolean inArea(int x, int y) {
return x >= 0 && x < R && y >= 0 && y < C;
}
}