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 0Return 4.
1. dp[i][j]记录matrix[i][j]点最大square的边长;dp[i][j] = 1 + min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]);
2. 有人提出了不使用额外空间的解法,是利用matrix本身来进行记录
int maximalSquare(vector<vector<char>>& matrix) {
if(matrix.empty()) return 0;
int m = matrix.size();
int n = matrix[0].size();
int dp[n+1];
fill_n(dp, n+1, 0); //初始化为0
int maxA = 0;
for(int i = 0; i < m; i++){
int leftCorner = 0; //左上角的值
for(int j = 0; j < n; j++){
int tmp = dp[j+1];
if(matrix[i][j] == '1'){
dp[j+1] = 1 + min(dp[j+1], min(dp[j], leftCorner));
}
else dp[j+1] = 0;
leftCorner = tmp;
}
for(int j = 0; j < n; j++){
maxA = max(maxA, dp[j+1] * dp[j+1]);
}
}
return maxA;
}
Maximal Rectangle
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle 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 0Return 6.
这道题弄的还不是很懂。
1. left, right记录的是包含matrix[i][j]的点及height[j]的左右边界。从largest historgram的角度想,当沿着一个方向遍历时,当前一个的高度小于当前高度时,边界会缩小;当前一高度大于等于当前高度时,边界时不变的。
2. left[i][j] = max(left[i-1][j], curLeft), right[i][j] = min(right[i-1][j], curRight), height[i] = height[i-1] + 1
3. 注意matrix[i][j] = 0时,要将其三个变量置为初始值,使下一行不受影响。
int maximalRectangle(vector<vector<char>>& matrix) {
if(matrix.empty()) return 0;
int m = matrix.size();
int n = matrix[0].size();
int left[n], right[n], height[n];
fill_n(left, n, 0); //记录左起第一个不为0的位置(上升最大高度处)
fill_n(right, n, n); //从右起最后一个0的位置(上升最大高度处)
fill_n(height, n, 0); //向上的最大高度
int maxA = 0;
for(int i = 0; i < m; i++){
int curLeft = 0;
for(int j = 0; j < n; j++){
if(matrix[i][j] == '0'){
left[j] = 0; //使下一行不受影响
curLeft = j + 1;
height[j] = 0;
}
else{
left[j] = max(left[j], curLeft); //这里的left[j]实际上是上一行的, 即left[i][j] = max(left[i-1][j], curLeft)
height[j]++;
}
}
int curRight = n;
for(int j = n-1; j > -1; j--){
if(matrix[i][j] == '1') right[j] = min(right[j], curRight);
else{
curRight = j;
right[j] = n; //使下一行不受影响
}
}
for(int j = 0; j < n; j++){
maxA = max((right[j] - left[j]) * height[j], maxA);
}
}
return maxA;
}
Note: This is an extension of House Robber.
After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.
分为两种情况:抢第一个店或者不抢第一个店 int rob(vector<int>& nums) {
int n = nums.size();
if(nums.empty()) return 0;
if(n < 2) return nums[0];
int amount = 0;
//do not rob the first
int two = 0, one = nums[1];
for(int i = 2; i < n; i++){
int cur = max(one, two + nums[i]);
two = one;
one = cur;
}
amount = one;
//rob the first
two = nums[0]; one = nums[0];
for(int i = 2; i < n - 1; i++){ //then he cannot rob the last house
int cur = max(one, two + nums[i]);
two = one;
one = cur;
}
return max(amount, one);
}