LeetCode: 剑指 Offer 12. 矩阵中的路径
描述:
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)。
boolean
数组, 记录当前哪些鲁走过. 如果当前已经走过了, 直接返回 false
false
word
的最后一个字符, 表示能够找到这么一条路径, 返回 true
board[i][j]
的时候, 将该位置的 boolean
数组置为 true
, 在回溯的时候, 将该boolean
置回 false
(i+1,j) , (i,j+1) , (i-1,j) , (i, j-1)
class Solution {
public boolean exist(char[][] board, String word) {
boolean[][] tmp = new boolean[board.length][board[0].length];
for (int i = 0; i < board.length; i++) {
for(int j = 0; j < board[0].length; j++) {
if(dfs(board,word,tmp,i,j,0)){
return true;
}
}
}
return false;
}
public boolean dfs(char[][] board, String word,boolean[][] tmp, int i, int j, int index) {
// 如果坐标不合法 返回false
// 如果对应的字符不一致, 返回false
// 如果已经被使用过了, 返回false
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || word.charAt(index) != board[i][j] || tmp[i][j]){
return false;
}
// 这里表示有一条路径了
if (index == word.length()-1) {
return true;
}
tmp[i][j] = true;
// 这里从四个方向去找, 只要有一条满足了, 就为true
boolean ans = dfs(board,word,tmp,i+1,j,index+1) || dfs(board,word,tmp,i,j+1,index+1) || dfs(board,word,tmp,i-1,j,index+1) || dfs(board,word,tmp,i,j-1,index+1);
tmp[i][j] = false;
return ans;
}
}
LeetCode: 279. 完全平方数
描述:
给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。
完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。
class Solution {
public int numSquares(int n) {
int[] dp = new int[n+1];
dp[0] = 0;
for(int i = 1; i <= n ; i++) {
// 这里首先要让他是最坏的情况. 例如dp[3] = 1 + 1 + 1 = 3
dp[i] = i;
for(int j = 1; j*j <= i ; j++) {
dp[i] = Math.min(dp[i - j * j] + 1, dp[i]);
}
}
return dp[n];
}
}
LeetCode: 96. 不同的二叉搜索树
描述:
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
状态转移方程:
当 j 为根节点时候, 左子树的节点为 j-1
个, 右子树的节点为 i-j
个
F(i) += F(j-1) * F(i-j)
初始状态 F(0) = 1, F(1) = 1
返回结果: F(n)
class Solution {
public int numTrees(int n) {
int[] dp = new int[n+1];
dp[0] = 1;
dp[1] = 1;
for(int i = 2; i < n + 1; i++) {
for(int j = 1; j < i + 1; j++) {
dp[i] += dp[j-1] * dp[i-j];
}
}
return dp[n];
}
}
LeetCode: 98. 验证二叉搜索树
描述:
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
class Solution {
private long pre = Long.MIN_VALUE;
public boolean isValidBST(TreeNode root) {
if(root == null) return true;
if(!isValidBST(root.left)) {
return false;
}
if(root.val <= pre) {
return false;
}
pre = root.val;
return isValidBST(root.right);
}
}
LeetCode: 5. 最长回文子串
描述:
给你一个字符串 s,找到 s 中最长的回文子串。
状态转移方程:
i == j, dp[i][j] = true
i + 1 == j, dp[i][j] = s.charAt(i) == s.charAt(j)
dp[i][j] = s.charAt(i) == s.charAt(j) && dp[i+1][j-1]
初始状态: i == j, dp[i][j] = true
返回结果, 最长的 j - i + 1, 返回 s.substring(i,j+1)
class Solution {
public String longestPalindrome(String s) {
if(s.length() == 1) return s;
boolean[][] dp = new boolean[s.length()][s.length()];
int maxLen = 1;
String ans = new String();
// 注意这里的遍历, 从后往前来
for(int i = s.length()-1; i >= 0; i--) {
for(int j = i; j < s.length(); j++) {
if(i == j) dp[i][j] = true;
else if(i+1 == j) dp[i][j] = s.charAt(i) == s.charAt(j);
else dp[i][j] = s.charAt(i) == s.charAt(j) && dp[i+1][j-1];
if(dp[i][j]){
if(j - i + 1 >= maxLen) {
maxLen = j - i + 1;
ans = s.substring(i,j+1);
}
}
}
}
return ans;
}
}
LeetCode: 647. 回文子串
描述:
给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。
回文字符串 是正着读和倒过来读一样的字符串。
子字符串 是字符串中的由连续字符组成的一个序列。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。
class Solution {
public int countSubstrings(String s) {
boolean[][] dp = new boolean[s.length()][s.length()];
int count = 0;
for(int i = s.length() - 1; i >= 0; i--) {
for(int j = i; j < s.length(); j++) {
if(i == j) {
count++;
dp[i][j] = true;
}else if(i+1 == j && s.charAt(i) == s.charAt(j)) {
count++;
dp[i][j] = true;
}else if(i+1 < j && s.charAt(i) == s.charAt(j) && dp[i+1][j-1]) {
count++;
dp[i][j] = true;
}
}
}
return count;
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://wangzhi430.blog.csdn.net/article/details/125705437
内容来源于网络,如有侵权,请联系作者删除!