367. Valid Perfect Square
(理论:平方数可以表示为 1 + 3 + 5 + 7 ...;或者利用二分法看看最后的start或者end有没有平方后等于给定的数)
279. Perfect Squares
利用动态规划:
一个长度为n + 1的数组,代表该数字 (0 - n)最少由多少个平方数乘积。dp[0] = 0.
其余初始化为Integer.MAX_VALUE
dp[i + j * j] = Math.min(dp[i + j * j], dp[i] + 1);
221. Maximal Square
动态规划:
状态方程:dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1;
dp 表示当前格可以形成的边长为多少的正方形。
注意答案是其平方,求的是面积
另外需要注意max在初始化第一行第一列时需要对应设置(in case of extreme cases)
422. Valid Word Square
根据定义,word square的充要条件是第n行与第n列内容相同。与对称矩阵的定义一样。x[i][j] = x[j][i]。
但是,这题需要注意的是,不一定需要是方阵;所以,x[j][i]不一定存在。(不存在有两种情况:j > row 或者j行的长度小于i,需要判断这两种情况)
367. Valid Perfect Square
Given a positive integer num, write a function which returns True if num is a perfect square else False.
Note: Do not use any built-in library function such as sqrt.
Example 1:
Input: 16
Returns: True
Example 2:
Input: 14
Returns: False
public class Solution {
// 两种思路:1)一个完全平方数肯定能表示为 1 + 3 + 5 ...所以,如果一个数 - 1 - 3 - ...
// 至其小于等于0后,检查这个数是否为0. 是的话则为完全平方数。
// 2) 利用二分搜索,看搜索后的start和end是否有一个平方后为给出的数
public boolean isPerfectSquare(int num) {
if (num < 0) {
return false;
}
if (num < 2) {
return true;
}
long numL = (long)num;
long start = 1;
long end = numL - 1;
long mid = 0;
while (start + 1 < end) {
mid = start + (end - start) / 2;
if (mid * mid == numL) {
return true;
}
if (mid * mid < numL) {
start = mid + 1;
} else {
end = mid - 1;
}
}
if (end * end == numL || start * start == numL) {
return true;
}
return false;
}
}
279. Perfect Squares
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.
For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9.
public class Solution {
// 这题的动态规划状态有点难想:
// 一个长度为n + 1的数组,代表该数字 (0 - n)最少由多少个平方数乘积。dp[0] = 0.
// 其余初始化为Integer.MAX_VALUE
// dp[i + j * j] = Math.min(dp[i + j * j], dp[i] + 1);
public int numSquares(int n) {
if (n < 2) {
return n;
}
int[] dp = new int[n + 1];
dp[0] = 0;
for (int t = 1; t <= n; t++) {
dp[t] = Integer.MAX_VALUE;
}
for (int i = 0; i <= n; i++) {
for (int j = 1; (i + j * j) <= n; j++) {
dp[i + j * j] = Math.min(dp[i + j * j], dp[i] + 1);
}
}
return dp[n];
}
}
221. Maximal Square
Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area.
For example, given the following matrix:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Return 4.
public class Solution {
//状态方程:dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1;
//dp 表示当前格可以形成的边长为多少的正方形。
//注意答案是其平方,求的是面积
//另外需要注意max在初始化第一行第一列时需要对应设置
public int maximalSquare(char[][] matrix) {
if (matrix == null || matrix.length == 0
|| matrix[0] == null || matrix[0].length == 0) {
return 0;
}
int row = matrix.length;
int col = matrix[0].length;
int[][] dp = new int[row][col];
/*初始化第一行第一列*/
dp[0][0] = matrix[0][0] == '0' ? 0 : 1;
int max = dp[0][0];
for (int t = 1; t < col; t++) {
dp[0][t] = matrix[0][t] == '0' ? 0 : 1;
if (max == 0) {
max = matrix[0][t] == '0' ? 0 : 1;
}
}
for (int t = 1; t < row; t++) {
dp[t][0] = matrix[t][0] == '0' ? 0 : 1;
if (max == 0) {
max = matrix[t][0] == '0' ? 0 : 1;
}
}
for (int i = 1; i < row; i++) {
for (int j = 1; j < col; j++) {
if (matrix[i][j] == '0') {
dp[i][j] = 0;
} else {
dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
if (dp[i][j] > max) {
max = dp[i][j];
}
}
}
}
return max * max;
}
}
422. Valid Word Square
Given a sequence of words, check whether it forms a valid word square.
A sequence of words forms a valid word square if the kth row and column read the exact same string, where 0 ≤ k < max(numRows, numColumns).
Note:
The number of words given is at least 1 and does not exceed 500.
Word length will be at least 1 and does not exceed 500.
Each word contains only lowercase English alphabet a-z.
public class Solution {
//根据定义,word square的充要条件是第n行与第n列内容相同。与对称矩阵的定义一样。x[i][j] = x[j][i]。
//但是,这题需要注意的是,不一定需要是方阵;所以,x[j][i]不一定存在。(不存在有两种情况:j > row 或者j行的长度小于i,需要判断这两种情况)
public boolean validWordSquare(List<String> words) {
if (words == null || words.size() < 1) {
return true;
}
int row = words.size();
for (int i = 0; i < row; i++) {
int col = words.get(i).length();
for (int j = 0; j < col; j++) {
if (j >= row || words.get(j).length() <= i
|| words.get(i).charAt(j) != words.get(j).charAt(i)) {
return false;
}
}
}
return true;
}
}