I am debugging on the following problem and posted problem statement and code. My question is, I think for loop (for i in range(m) and for j in xrange(n)) is not correct, since it only consider rectangles from the top row? Please feel free to correct me if I am wrong. Thanks.
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
def maximalRectangle(self, matrix):
if not matrix:
return 0
m, n, A = len(matrix), len(matrix[0]), 0
height = [0 for _ in range(n)]
for i in range(m):
for j in xrange(n):
height[j] = height[j]+1 if matrix[i][j]=="1" else 0
A = max(A, self.largestRectangleArea(height))
return A
def largestRectangleArea(self, height):
height.append(0)
stack, A = [0], 0
for i in range(1, len(height)):
while stack and height[stack[-1]] > height[i]:
h = height[stack.pop()]
w = i if not stack else i-stack[-1]-1
A = max(A, w*h)
stack.append(i)
return A
My solution in Java:
public class Solution {
public int maximalSquare(char[][] matrix) {
if (matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
int rows = matrix.length;
int cols = matrix[0].length;
int[][] length = new int[rows][cols];
int result = 0;
for (int i = 0; i < rows; i++) {
length[i][0] = Character.getNumericValue(matrix[i][0]);
result = Math.max(result, length[i][0]);
}
for (int j = 0; j < cols; j++) {
length[0][j] = Character.getNumericValue(matrix[0][j]);
result = Math.max(result, length[0][j]);
}
for (int i = 1; i < rows; i++) {
for (int j = 1; j < cols; j++) {
if (matrix[i][j] == '1') {
length[i][j] = Math.min(
Math.min(length[i - 1][j], length[i][j - 1]),
length[i - 1][j - 1]) + 1;
result = Math.max(result, length[i][j] * length[i][j]);
}
}
}
return result;
}
}
Related
I'm currently working on a robust optimization of the VRP with CPLEX Studio and at the moment I'm not getting anywhere.
Setting up the deterministic problem is no problem so far, but I am failing at implementing the uncertainty. I am working with uncertainty sets and would like to secure my tour plan against all worst case scenarios. Does anyone have an idea how I can make sure that all possible scenarios are considered? So far, my optimization does calculate a random deviation, but this only affects one scenario and thus does not result in a robust tour plan.
In detail, this means, for example: Transportation time t[1,2] = 300 in the normal case. In addition, there are 30 minutes of delay - but in each scenario only at Γ edges.
The original language of the program is OPL, but if you have any hints for Python or Excel, I would be very grateful too.
// parameters & sets
int n = ...; // amount of customers
{int} N = asSet(1..n); // set of customers
{int} N0 = {0} union N union {n+1}; // set of customer incl. depots
int m = ...; // amount of vehicles
{int} M = asSet(1..m); // set of vehicles
float Q = ...; // capacity
int r[N]= ...; // demand
int b[N]= ...;// deadline
tuple Kanten {int i ; int j;};
{Kanten} A = {<i,j> | i in N0, j in N0}; // Kantenmenge A
execute {writeln (A);}
//{Kanten} B = {<i,j> | i in N0, j in N0}; // Kantenmenge B
//execute {writeln (B);}
int K = 9999; // large number
float d[N0,N0]= ...; // max deviation of travel time
float o [N]= ...; // max deviation of demand
float G = ...; // uncertainty budget of travel time
float L = ...; // uncertainty budget of demand
float t[N0, N0] = ...; // travel time matrix
{float} td ={t[i,j] * (1+d[i,j]) | i,j in N0}; // Depotverbindung ausblenden
float proba[N0,N0]=...; // wie i,j == j,i?
int c[N0, N0] = ...; // distance matrix
// optimization model
// decision variables
dvar boolean x[N0, N0, M];
dvar float+ s[N0, M];
dvar float+ p[N,M];
dvar float+ z[M];
dvar boolean u[N0,N0];
execute{ // indicator function
for (var i in N0){
for (var j in N0){
if (t[i][j] == td[i][j]){
u[i][j] == 0;
}
else {
u[i][j] == 1;
}
}
}
};
// objective function
minimize sum(k in M) sum(i in N0) sum(j in N0) c[i,j]*x[i,j,k];
// constraints
subject to {
// (2)
NB2:forall (i in N) {
sum (k in M) sum (j in N: j!=i) x[i,j,k] == 1;
};
// (3)
NB3:forall (k in M) {
sum (j in N0: j !=0) x[0,j,k] == 1;
};
// (4)
NB4:forall (i in N, k in M) {
sum (j in N0) x[i,j,k] - sum (j in N0: j!=i) x[j,i,k] == 0;
};
// (5)
NB5:forall (k in M) {
sum (i in N0: i!=6) x[i,(n+1),k] == 1;
};
// (11)
NB11: forall (k in M) {
sum (i in N) r[i] * sum (j in N0: j!=i) x[i,j,k] + L*z[k] + sum (i in N) p[i,k] <= Q ;
};
// (12)
NB12: forall (k in M, i,j in N: i!=j) {
z[k] + p[i,k] >= o[i] * t[i,j] * sum (j in N0) x[i,j,k];
};
// (13)
NB13: forall (i,j in N0: i!=j, k in M) { // if else Befehl für td und t?
s[i,k] + t[i,j] + d[i,j] * u [i,j] - K * (1 - x [i,j,k]) <= s[j,k] ; // Wie A + B berücksichtigen? U berücksichtigen notwendig?
};
/*execute{ // indicator function
for (var i in N0){
for (var j in N0){
for (var k in M){
if (t[i][j] == td[i][j]){
s[i,k] + t[i,j] - K * (1 - x [i,j,k]) <= s[j,k];
}
else {
s[i,k] + t[i,j] + d[i,j] * u [i,j] - K * (1 - x [i,j,k]) <= s[j,k]
}
}
}
}
};*/
// (14)
NB14: forall (i in N, k in M) { // N oder N0?
0 <= s[i,k] <= b[i];
};
//eigene Ergänzungen
/* // (15)
NB15: forall (k in M, i in N0, j in N0: i==j) {
x[i,j,k] == 0;
};
// (16)
NB16: forall (i in N0, k in M) {
s[0,k] == 0;
};
// (17)
NB17: forall (i,j in N0: i== j) {
u[i,j] == 0;
}
// (18)
NB18: forall (i,j in N0, k in M){
x[0,6,k] == 0;
}*/
};
a tiny robust optimization model to start with https://github.com/AlexFleischerParis/zooopl/blob/master/zoorobust.mod in Easy optimization
int nbKids=300;
{int} nbKidsScenarii={nbKids+i*10 | i in -10..2};
float proba[nbKidsScenarii]=[ 1, 1, 2, 2, 2 ,3 ,3 ,4, 5 ,10 ,50 ,10, 7];
assert sum(s in nbKidsScenarii) proba[s]==100; // total probability is 100
float costBus40=500;
float costBus30=400;
int alpha=80; // We want the constraint to be ok with probability 0.95
dvar int+ nbBus40;
dvar int+ nbBus30;
minimize
costBus40*nbBus40 +nbBus30*costBus30;
subject to
{
ctKids:alpha<=sum(nbKids in nbKidsScenarii)
(40*nbBus40+nbBus30*30>=nbKids)*proba[nbKids];
}
execute
{
writeln("nbBus40 = ",nbBus40);
writeln("nbBus30 = ",nbBus30);
}
I am trying to convert my code in python for game of life to C. But I am encountering some issues, also since I'd need to use it for multiple generation, I'd need to use an type int function and return board as a 2-d array. But I am not sure what is the best way of doing so. Below is the code in python and C. Also, I'm stuck with the nested loop, but could not figure out why I am getting the seg faults.
void game_of_life(int board[5][5]) {
int m = 5;
int n = 5;
int moves[8][2] = {{-1, 1},
{-1, 0},
{-1, -1},
{0, -1},
{0, 1},
{1, 0},
{1, -1},
{1, 1}};
int dm = 8;
int grid[m][n];
memcpy(board, grid, sizeof(grid));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; i++) {
int total = 0;
for (int k = 0; k < dm; k++) {
int cr = i + moves[k][0];
int cc = j + moves[k][1];
if (cr >= 0 && cr < m && cc >= 0 && cc < n) {
total += board[cr][cc];
printf("%d", total);
}
}
if (total < 2 || total > 3) {
board[i][j] = 0;
} else if (total == 3) {
board[i][j] = 1;
} else {
board[i][j] = grid[i][j];
}
}
}
for(int k =0; k < 5; k++)
{
for(int l=0; l<5; l++)
{
printf("%d", board[k][l]);
}
printf("\n");
}
}
m = len(board)
n = len(board[0])
moves = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, 0), (1, -1), (1, 1)] # eight possible neighbors
grid = [row[:] for row in board] # make a copy of the grid
for i in range(m):
for j in range(n): # for each cell, check how many neighbors alive
total = 0
for di, dj in moves: # check every neighbor
cr = i + di # finding the xy-index of neighbor
cc = j + dj
if 0 <= cr < m and 0 <= cc < n: # check if it falls in valid range
total += grid[cr][cc] # increment the total neighbor alive for current cell
if total < 2 or total > 3: # if the total is less than 2 or greater than three, set the value to 0
board[i][j] = 0
elif total == 3: # if the total is 3, set the value to 1
board[i][j] = 1
print(i,j, board[i][j])
else: # else, the value remains unchanged, copy it from the original grid
board[i][j] = grid[i][j]
return board
Using gdb, I was able to figure out that It would crash at
if (total < 2 || total > 3) {
board[i][j] = 0;
} else if (total == 3) {
because i was 548
Look at your loops.
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; i++) {
int total = 0;
for (int k = 0; k < dm; k++) {
int cr = i + moves[k][0];
int cc = j + moves[k][1];
in the second one, you do i++ again. Change it to j++
If you're going to copy+paste your nested loops, make sure you pay attention to details like this so you don't end up with confusing and simple errors.
I came across some classical Knapsack solutions and they always build a 2-dimensional DP array.
In my opinion, my code below solves the classical knapsack problem but with only a 1-dim DP array.
Can someone tell me where my solution does not work or why it is computationally inefficient compared to the 2D-DP version?
A 2D-DP version can be found here
https://www.geeksforgeeks.org/python-program-for-dynamic-programming-set-10-0-1-knapsack-problem/
example input:
weights = [(3,30),(2,20),(1,50),(4,30)]
constraint = 5
And my solution:
def knapsack(weights,constraint):
n = len(weights)
#define dp array
dp = [0]*(constraint+1)
#start filling in the array
for k in weights:
for i in range(constraint,k[0]-1,-1):
dp[i] = max(dp[i],dp[i-k[0]]+k[1])
return dp[constraint]
The version using O(nW) memory is more intuitive and makes it possible to easily retrieve the subset of items that produce the optimal answer value.
But, using O(n + W) of memory, we cannot retrieve this subset directly. While it is possible to do this, using the divide-and-conquer technique as explained in https://codeforces.com/blog/entry/47247?#comment-316200.
Sample code
#include <bits/stdc++.h>
using namespace std;
using vi = vector<int>;
#define FOR(i, b) for(int i = 0; i < (b); i++)
template<class T>
struct Knapsack{
int n, W;
vector<T> dp, vl;
vi ans, opt, wg;
Knapsack(int n_, int W): n(0), W(W),
dp(W + 1), vl(n_), opt(W + 1), wg(n_){}
void Add(T v, int w){
vl[n] = v;
wg[n++] = w;
}
T conquer(int l, int r, int W){
if(l == r){
if(W >= wg[l])
return ans.push_back(l), vl[l];
return 0;
}
FOR(i, W + 1)
opt[i] = dp[i] = 0;
int m = (l + r) >> 1;
for(int i = l; i <= r; i++)
for(int sz = W; sz >= wg[i]; sz--){
T dpCur = dp[sz - wg[i]] + vl[i];
if(dpCur > dp[sz]){
dp[sz] = dpCur;
opt[sz] = i <= m ? sz : opt[sz - wg[i]];
}
}
T ret = dp[W];
int K = opt[W];
T ret2 = conquer(l, m, K) + conquer(m + 1, r, W - K);
assert(ret2 == ret);
return ret;
}
T Solve(){
return conquer(0, n - 1, W);
}
};
int main(){
cin.tie(0)->sync_with_stdio(0);
int n, W, vl, wg;
cin >> n >> W;
Knapsack<int> ks(n, W);
FOR(i, n){
cin >> vl >> wg;
ks.Add(vl, wg);
}
cout << ks.Solve() << endl;
}
Link to the question: https://leetcode.com/problems/number-of-islands/
Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
Example 1:
Input:
11110
11010
11000
00000
Output: 1
My logic is to simply do dfs from every node and keep track of the connected components.
Am getting Time Limit Exceeded (TLE) for the 46th test case, can someone help me optimize this code?
class Solution(object):
def numIslands(self, grid):
def in_grid(x, y):
return 0 <= x < len(grid) and 0 <= y < len(grid[0])
def neighbours(node):
p, q = node
dir = [(-1, 0), (0, 1), (1, 0), (0, -1)]
return [(x, y) for x, y in [(p + i, q + j) for i, j in dir] if in_grid(x, y)]
def dfs(node):
visited.append(node)
for v in neighbours(node):
if grid[v[0]][v[1]]== "1" and v not in visited:
dfs(v)
components = 0
visited = []
for i in range(len(grid)):
for j in range(len(grid[0])):
node = (i, j)
if grid[i][j] == "1" and node not in visited:
components += 1
dfs(node)
return components
I think your approach is correct. However you are using visited as a list which takes O(n) to search a value. So its overall time complexity is O(N^2). I would suggest to use set rather than list which is a hash table.
There is just two parts to revise:
visited = [] -> visited = set()
visited.append(node) ->visited.add(node)
I confirmed that it is accepted. Now node not in visited takes O(1) so the overall time complexity is O(N).
% Like most of other LeetCode problems, the problem statement does not give any information about input data. But as your code is TLE so we can assume that we cannot solve it with time complexity O(n^2).
The reason you are getting TLE is that you are using a list to keep a track of visited nodes. The search of a value in a list takes O(n) time in the worst case.
It's optimal to keep the index status of a visited/non-visited node as a 2D matrix containing boolean values or O/1 integer values. This leads to a constant access time O(1) to find the visited/non-visited status of a node.
class Solution {
boolean isSafe(char[][] grid, int[][] visited, int i, int j)
{
int n = grid.length;
int m = grid[0].length;
if((i<0 || i>n-1) || (j<0 || j>m-1))
return false;
return visited[i][j] == 0 && grid[i][j] == '1';
}
void DFS(char[][] grid, int[][] visited, int i, int j)
{
visited[i][j] = 1; //marked visited
int[] row = {-1, 0, 1, 0};
int[] column = {0, 1, 0, -1};
for(int k = 0; k<4; k++)
{
if(isSafe(grid, visited, i+row[k], j+column[k]))
{
DFS(grid, visited, i+row[k], j+column[k]);
}
}
}
int DFSUtil(char[][] grid)
{
int count = 0;
if(grid == null || grid.length == 0)
return count;
int n = grid.length; //rows
int m = grid[0].length; //columns
int[][] visited = new int[n][m];
for(int i = 0; i<n; i++)
for(int j = 0; j<m; j++)
{
if(grid[i][j]=='1' && visited[i][j] == 0)
{
DFS(grid, visited, i, j);
count++;
}
}
return count;
}
public int numIslands(char[][] grid) {
int result = DFSUtil(grid);
return result;
}
}
I solved it in Java by a DFS approach, it's simple and easy to understand. Here, my code may help you:
public static int numIslands(char[][] grid) {
int countOfIslands = 0 ;
for (int i = 0; i <grid.length ; i++) {
for (int j = 0; j <grid[i].length ; j++) {
if(grid[i][j] == '1'){
DFS(grid,i,j);
countOfIslands++;
}
}
}
return countOfIslands;
}
public static void DFS(char[][] grid , int row , int col){
if(grid[row][col] == '0')
return;
grid[row][col] = '0';
// System.out.println("grid = " + Arrays.deepToString(grid) + ", row = " + row + ", col = " + col);
if(row+1 < grid.length)
DFS(grid,row+1,col);
if(row-1 >=0)
DFS(grid,row-1,col);
if(col+1 <grid[0].length)
DFS(grid,row,col+1);
if(col-1 >= 0)
DFS(grid,row,col-1);
}
Reference for if this is your first time hearing about the DFS for a graph:
DFS Approach
Modified Simple DFS Solution
class Solution {
public int numIslands(char[][] grid) {
int count = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (grid[i][j] != '0') {
count++;
shrink(grid, i, j);
}
}
}
return count;
}
private void shrink(char[][] grid, int i, int j) {
if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] ==
'0')
return;
grid[i][j] = '0';
shrink(grid, i, j+1);
shrink(grid, i, j-1);
shrink(grid, i+1, j);
shrink(grid, i-1, j);
}
}
Given a positive integer N, print all integers between 1 and 2^N such that there is no consecutive 1’s in its Binary representation.
I have below code but it is printing duplicate sometimes. Is it possible to print without duplicates?
#include <stdio.h>
int a[100];
void foo(int i, int size)
{
if (i >= size) {
int i;
for (i=0;i<size;i++)
printf("%d\n", a[i]);
printf("----\n");
return;
}
if (a[i-1] == 1 || a[i-1] == 0)
a[i] = 0;
foo(i+1, size);
if (a[i-1] == 0)
a[i] = 1;
foo(i+1, size);
}
int main(void) {
int i = 0;
int size = 5;
a[i] = 1;
foo(1, size);
return 0;
}
I have this http://ideone.com/cT4Hco python program which uses hash maps to print the elements but I think we can do this without hashmaps also.
Couple of notes:
you shouldn't start the backtracking from index 1. Instead, start from 0 since your numbers would be in the range [0, n-1] in array a
you shouldn't initialize a[0] to 1 since a[0] = 0 is also a valid case.
if (a[i-1] == 1 || a[i-1] == 0) is redundant
Code:
#include <stdio.h>
int a[100];
void foo(int i, int size)
{
if (i >= size) {
int i;
for (i=0;i<size;i++)
printf("%d ", a[i]);
printf("\n----\n");
return;
}
a[i] = 0;
foo(i+1, size);
if ( i == 0 || a[i-1] == 0) {
a[i] = 1;
foo(i+1, size);
}
}
int main(void) {
int i = 0;
int size = 5;
foo(0, size);
return 0;
}
You might also want to filter the solution 0 0 0 ... 0 during the printing since you need only the numbers from 1 to 2^n. If 2^n is included you should also print it. The backtracking considers the numbers 0, ...., 2^n-1