Why my dfs code is not working in word search problem? - depth-first-search

**this solution is always return 0 My idea is I traverse dfs in four sides and check the condition **```
#include<bits/stdc++.h>
using namespace std;
// } Driver Code Ends
class Solution {
public:
bool dfs(int i,int j,int idx,vector<vector> & board, string & word,vector<vector> & vis
,int del_row[],int del_col[]){
if(idx == word.size()){
return true;
}
vis[i][j]=1;
int n = board.size();
int m = board[0].size();
for(int k=0;k< 4 ;k++){
int row = i + del_row[k];
int col = j + del_col[k];
if( row >= 0 && col >= 0 && row < n && col < m && vis[i][j]== 0 &&
board[row][col] == word[idx]){
if(dfs(row,col,idx+1,board,word,vis,del_row,del_col)){
return true;
}
}
}
vis[i][j] =0;
return false;
}
bool isWordExist(vector<vector<char>>& board, string word) {
// Code here
int n = board.size();
int m = board[0].size();
vector<vector<int>> vis(n,vector<int>(m,0));
int del_row [] = {-1,+1,0,0};
int del_col [] = {0,0,-1,+1};
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(board[i][j] == word[0] && !vis[i][j]){
if(dfs(i,j,1,board,word,vis,del_row,del_col)){
return true;
}
}
}
}
return false;
}
};
this code is always return 0 .

Related

Finding minimum height of binary tree with given inorder and level-order traversals

The inorder and levelorder traversals for a binary tree along with the total number of nodes is given in a function definition, we have to calculate the minimum height of binary tree for the given inputs.
Can we calculate without constructing the tree?
func(int[] inorder, int[] levelorder, int n)
{
// write code here
}
for example
inorder traversal - { 4,2,5,1,6,3,7},
levelorder traversal - {1,2,3,4,5,6,7}, n=7.
And expected o/p was 3
Below code snippet would calculate the height of the tree without constructing it.
#include <iostream>
#include <queue>
using namespace std;
int minHeight(int inOrder[], int levelOrder[], int n)
{
int i=1;
queue<int>q1,q2;
q1.push(levelOrder[0]);
int k = 1,height = 0;
while(!q1.empty() || !q2.empty()){
if(!q1.empty()) height++;
while(!q1.empty()){
int val = q1.front();
for(int i = 0;i<n;++i){
if(inOrder[i] == val) break;
}
if(i>0 && inOrder[i-1] !=-1 && k<n)
q2.push(levelOrder[k++]);
if(i<n-1 && inOrder[i+1] !=-1 && k<n)
q2.push(levelOrder[k++]);
inOrder[i] = -1;
q1.pop();
}
if(!q2.empty()) height++;
while(!q2.empty()){
int val = q2.front();
for(int i = 0;i<n;++i){
if(inOrder[i] == val) break;
}
if(i>0 && inOrder[i-1] !=-1 && k<n)
q1.push(levelOrder[k++]);
if(i<n-1 && inOrder[i+1] !=-1 && k<n)
q1.push(levelOrder[k++]);
inOrder[i] = -1;
q2.pop();
}
}
return height;
}
int main()
{
int inOrder[] = {4,2,5,1,6,3,7}; //input1
int levelOrder[] = {1,2,3,4,5,6,7}; //input2
int n=sizeof(inOrder)/sizeof(int); ////input3
cout<<minHeight(inOrder, levelOrder, n)<<endl;
return 0;
}
Question : If the in-order and level order traversal of a tree are given, what is the minimum height of the tree
Example 1 :
input1 : {2,1,3}
input2 : {1,2,3}
input3 : 3
Output : 2
Example 2 :
input1 : {4,2,5,2,6,3,7}
input2 : {1,2,3,4,5,6,7}
input3 : 7
Output : 3
If you got this question in Campus round of Naggaro or on metti then it will a good solution for you
class Node:
def __init__(self, key):
self.data = key
self.left = None
self.right = None
def buildTree(level, ino):
if ino:
for i in range(0, len(level)):
if level[i] in ino:
node = Node(level[i])
io_index = ino.index(level[i])
break
if not ino:
return node
node.left = buildTree(level, ino[0:io_index])
node.right = buildTree(level, ino[io_index + 1:len(ino)])
return node
def height(root):
if root is None:
return 0
else:
return max(height(root.left),height(root.right))+1
#This is the function you have to write
def minHeight(input1,input2,input3):
global root
root = buildTree(input1, input2)
return height(root)
inorder = [4,2,5,1,6,3,7]
levelorder = [1,2,3,4,5,6,7]
print("height : ",minHeight(levelorder,inorder,len(inorder)))
a very simple approach is to build the tree and then find it's height.
let's suppose structure of the node is :
struct Node
{
int key;
struct Node* left, *right;
};
Node* **newNode**(int key)
{
Node *node = (Node *)malloc(sizeof(Node));
node->key = key;
node->left = node->right = NULL;
return (node);
}
int **getHeight**(Node* root){
if(root==NULL) return 0;
return max(getHeight(root->left)+1,getHeight(root->right)+1);
}
Node* **getNode**(Node* root,int key){
if(root!=NULL){
if(root->key == key) return root;
return getNode(root->left,key) != NULL ? getNode(root->left,key):
getNode(root->right,key);
}
}
void **buildTree**(int inorder[], int levelOrder[], int i, int j,int n)
{
Node* head = newNode(levelOrder[0]);
i++;
int comp = 0;
while(i<j){
int key = levelOrder[comp];
Node* ptr = getNode(head,key);
int k = n-1;
while(k>=0 && inorder[k]!=key) k--;
if(k>0 && inorder[k-1]!=-1){
ptr->left = newNode(levelOrder[i]);
i++;
}
if(k<n-1 && inorder[k+1]!=-1){
ptr->right = newNode(levelOrder[i]);
i++;
}
inorder[k] = -1;
comp++;
}
int height = getHeight(head);
**cout<<height<<" ";**
}
yes, you can do that without even constructing the tree.
for that use two queue.
see given below code for better understanding.
void **buildTree**(int inorder[], int levelOrder[], int i, int j,int n)
{
queue<int>q1,q2;
q1.push(levelOrder[0]);
int k = 1,height = 0;
while(!q1.empty() || !q2.empty()){
if(!q1.empty()) height++;
while(!q1.empty()){
int val = q1.front();
for(int i = 0;i<n;++i){
if(inorder[i] == val) break;
}
if(i>0 && inorder[i-1] !=-1 && k<n)
q2.push(levelOrder[k++]);
if(i<n-1 && inorder[i+1] !=-1 && k<n)
q2.push(levelOrder[k++]);
inorder[i] = -1;
q1.pop();
}
if(!q2.empty()) height++;
while(!q2.empty()){
int val = q2.front();
for(int i = 0;i<n;++i){
if(inorder[i] == val) break;
}
if(i>0 && inorder[i-1] !=-1 && k<n)
q1.push(levelOrder[k++]);
if(i<n-1 && inorder[i+1] !=-1 && k<n)
q1.push(levelOrder[k++]);
inorder[i] = -1;
q2.pop();
}
}
cout<<height<<endl;
}
The minimum possible height of a binary tree is log2(n+1), where n is the number of nodes.

Special minimum spanning tree

There is a node that can only get one line, I use both kruskal and prim, but the judger said TLE(Time Limit Exceed).
Then I will describe the question. There are many computers, we need to connect all of them, we give the cost of connection between different computers, also we give the special number of computer which can be only connected by one line. Finally, we guarantee there is a answer and there is no Self-Loop, but there may have multiple edge which have different weight between same node.
Here is my kruskal code, it's TLE.
#include <iostream>
#include <algorithm>
using namespace std;
typedef struct edge{
int start;
int end;
int weight;
}Edge;
int special = 0;
int edgenum;
Edge _edge[600005];
int i, j, k;
int counter = 0;
bool Cmp(const edge &a, const edge &b){
return a.weight < b.weight;
}
int getEnd(int vends[], int i){
while(vends[i] != 0)
i = vends[i];
return i;
}
void kruskal(){
int p1, p2, m, n, ans = 0;
int vends[10005] = {0};
sort(_edge, _edge+counter, Cmp);
for(i = 0; i < edgenum; ++i){
p1 = _edge[i].start;
p2 = _edge[i].end;
if ((p1 == k || p2 == k) && special)
continue;
m = getEnd(vends, p1);
n = getEnd(vends, p2);
if(m != n){
if (p1 == k || p2 == k)
special = 1;
vends[m] = n;
ans += _edge[i].weight;
}
}
cout << ans << endl;
}
int main(){
int n, m;
cin >> n >> m >> k;
edgenum = m;
while(m--){
int a, b, c;
cin >> a >> b >> c;
_edge[counter].start = a; //Get the Edge
_edge[counter].weight = c;
_edge[counter++].end = b;
// _edge[counter].start = b;
// _edge[counter].weight = c;
// _edge[counter++].end = a;
}
kruskal();
}
Here is my Prim, but also TLE:
#include <iostream>
using namespace std;
typedef char VertexType;
typedef struct node{
int adjvex = 0;
int weight = INT32_MAX;
struct node *next = NULL;
}Node;
typedef struct vnode{
VertexType data;
Node *firstnode = NULL;
}Vnode;
Vnode node[10005];
int VNUM;
int n, m, k;
int lowcost[10005] = {0};
int addvnew[10005]; //未加入最小生成树表示为-1,加入则为0
int adjecent[10005] = {0};
bool is_special = false;
int flag;
void prim(int start){
long long sumweight = 0;
int i, j;
Node *p = node[start].firstnode;
for (i = 1; i <= VNUM; ++i) { //重置
addvnew[i] = -1;
}
while (p->next != NULL){
if (lowcost[p->adjvex] == 0 || p->weight < lowcost[p->adjvex])
lowcost[p->adjvex] = p->weight;
p = p->next;
}
if (lowcost[p->adjvex] == 0 || p->weight < lowcost[p->adjvex])
lowcost[p->adjvex] = p->weight;
addvnew[start] = 0;
// adjecent[start] = start;
if (start == k) {
is_special = true;
flag = 1;
}
for (i = 1; i < VNUM; ++i) {
int min = INT32_MAX;
int v=-1;
for (j = 1; j <= VNUM; ++j) { //Find the min
if (addvnew[j] == -1 && lowcost[j] < min && lowcost[j] != 0){
min = lowcost[j];
v = j;
}
}
if (v != -1){ //if min is found
if (flag == 1){
for (int l = 0; l < 10005; ++l) {
lowcost[l] = 0;
}
flag = 0;
}
addvnew[v] = 0;
sumweight += min;
p = node[v].firstnode;
while(p->next != NULL){
if (is_special && p->adjvex == k){ //If find the special node
p = p->next;
continue;
}
if(addvnew[p->adjvex] == -1 && (lowcost[p->adjvex] == 0 || p->weight < lowcost[p->adjvex])){ //如果该点未连接
lowcost[p->adjvex] = p->weight;
}
p = p->next;
}
if (!(is_special && p->adjvex == k))
if(addvnew[p->adjvex] == -1 && (lowcost[p->adjvex] == 0 || p->weight < lowcost[p->adjvex])){
lowcost[p->adjvex] = p->weight;
}
}
}
cout << sumweight << endl;
}
int main(){
cin >> n >> m >> k;
VNUM = n;
while (m--){
int a, b, c;
cin >> a >> b >> c;
Node *p = (Node*)malloc(sizeof(Node));
p->adjvex = b;
p->weight = c;
p->next = node[a].firstnode;
node[a].firstnode = p;
Node *q = (Node*)malloc(sizeof(Node));
q->adjvex = a;
q->weight = c;
q->next = node[b].firstnode;
node[b].firstnode = q;
}
prim(k);
}
I don't know how to modify the both code, I try my best, thank you

Finding longest sequence of '1's in a binary array by replacing any one '0' with '1'

I have an array which is constituted of only 0s and 1s. Task is to find index of a 0, replacing which with a 1 results in the longest possible sequence of ones for the given array.
Solution has to work within O(n) time and O(1) space.
Eg:
Array - 011101101001
Answer - 4 ( that produces 011111101001)
My Approach gives me a result better than O(n2) but times out on long string inputs.
int findIndex(int[] a){
int maxlength = 0; int maxIndex= -1;
int n=a.length;
int i=0;
while(true){
if( a[i] == 0 ){
int leftLenght=0;
int j=i-1;
//finding count of 1s to left of this zero
while(j>=0){
if(a[j]!=1){
break;
}
leftLenght++;
j--;
}
int rightLenght=0;
j=i+1;
// finding count of 1s to right of this zero
while(j<n){
if(a[j]!=1){
break;
}
rightLenght++;
j++;
}
if(maxlength < leftLenght+rightLenght + 1){
maxlength = leftLenght+rightLenght + 1;
maxIndex = i;
}
}
if(i == n-1){
break;
}
i++;
}
return maxIndex;
}
The approach is simple, you just need to maintain two numbers while iterating through the array, the current count of the continuous block of one, and the last continuous block of one, which separated by zero.
Note: this solution assumes that there will be at least one zero in the array, otherwise, it will return -1
int cal(int[]data){
int last = 0;
int cur = 0;
int max = 0;
int start = -1;
int index = -1;
for(int i = 0; i < data.length; i++){
if(data[i] == 0){
if(max < 1 + last + cur){
max = 1 + last + cur;
if(start != -1){
index = start;
}else{
index = i;
}
}
last = cur;
start = i;
cur = 0;
}else{
cur++;
}
}
if(cur != 0 && start != -1){
if(max < 1 + last + cur){
return start;
}
}
return index;
}
O(n) time, O(1) space
Live demo: https://ideone.com/1hjS25
I believe the problem can we solved by just maintaining a variable which stores the last trails of 1's that we saw before reaching a '0'.
int last_trail = 0;
int cur_trail = 0;
int last_seen = -1;
int ans = 0, maxVal = 0;
for(int i = 0; i < a.size(); i++) {
if(a[i] == '0') {
if(cur_trail + last_trail + 1 > maxVal) {
maxVal = cur_trail + last_trail + 1;
ans = last_seen;
}
last_trail = cur_trail;
cur_trail = 0;
last_seen = i;
} else {
cur_trail++;
}
}
if(cur_trail + last_trail + 1 > maxVal && last_seen > -1) {
maxVal = cur_trail + last_trail + 1;
ans = last_seen;
}
This can be solved by a technique that is known as two pointers. Most two-pointers use O(1) space and O(n) time.
Code : https://www.ideone.com/N8bznU
#include <iostream>
#include <string>
using namespace std;
int findOptimal(string &s) {
s += '0'; // add a sentinel 0
int best_zero = -1;
int prev_zero = -1;
int zeros_in_interval = 0;
int start = 0;
int best_answer = -1;
for(int i = 0; i < (int)s.length(); ++i) {
if(s[i] == '1') continue;
else if(s[i] == '0' and zeros_in_interval == 0) {
zeros_in_interval++;
prev_zero = i;
}
else if(s[i] == '0' and zeros_in_interval == 1) {
int curr_answer = i - start; // [start, i) only contains one 0
cout << "tried this : [" << s.substr(start, i - start) << "]\n";
if(curr_answer > best_answer) {
best_answer = curr_answer;
best_zero = prev_zero;
}
start = prev_zero + 1;
prev_zero = i;
}
}
cout << "Answer = " << best_zero << endl;
return best_zero;
}
int main() {
string input = "011101101001";
findOptimal(input);
return 0;
}
This is an implementation in C++. The output looks like this:
tried this : [0111]
tried this : [111011]
tried this : [1101]
tried this : [10]
tried this : [01]
Answer = 4

How to find edges in route

Let's say I have a graph like this
I want to find all the edges from 1 to 3 i.e. 1 2... 2 4... 4 3. I can write the code for 1 to 5 quite easily but when the next node in descending order then my code doesn't work. Please help me with that.
Here is my code:-
given if there is edge between i and j then:-
arr[i][j]=0
where s is total number of nodes and i have to find edges between a and b
for(int i=a;i!=b;)
{
for(int j=1;j<=s;j++)
{
if(arr[i][j]==0)
{
//cout<<i<<" "<<j<<endl;
i=j;
}
}
}
This can be solved using Breadth first search algorithm we can keep track of the parent of the current node while performing a BFS, and then can construct the path from that if the path exists, i have written a c++ solution below
#include<iostream>
#include<queue>
using namespace std;
int n, arr[100][100], par[100], vis[100], ans[100];
void bfs(int start, int end){
queue<int> Q;
Q.push(start);
par[start] = -1;vis[start] = 1;
bool found = false;
while(Q.size() > 0){
int v = Q.front();
Q.pop();
if(v == end){
found = true;
break;
}
for(int i = 1;i <= n;i++){
if(arr[v][i] == 0 || vis[i] == 1) continue;
Q.push(i);vis[i] = 1;
par[i] = v;
}
}
if(found == false){
cout << "No Path Found" << endl;return;
}
int curr = end, len = 0;
while(curr != -1){
ans[len++] = curr;
curr = par[curr];
}
for(int i = len-1;i >= 1;i--) cout << ans[i] << " " << ans[i-1] << endl;
}
int main(){
n = 5;
arr[1][2] = 1;arr[2][1] = 1;
arr[2][4] = 1;arr[4][2] = 1;
arr[4][5] = 1;arr[5][4] = 1;
arr[3][4] = 1;arr[4][3] = 1;
bfs(1, 3);
return 0;
}
Link to solution on Ideone : http://ideone.com/X8QnNu

Find the largest rectangle dimension

Given a matrix of ‘O’ and ‘X’, find the largest rectangle whose sides consist of ‘X’
Example 1
XXXXX
X0X0X
XXXXX
XXXXX
Output : largest rectangle size is 4 x 5
Example 2
0X0XX
X0X0X
XXXXX
XXXXX
Output: largest rectangle size is 2 x 5 (last two rows of the matrix)
I am able to make o(n4) algorithm in which I look for each combination. Can anybody please give some hints or idea for better optimized algorithm.
My Code:
#include<iostream>
#include<vector>
using namespace std;
int arr[1001][1001];
int check(int left[][1001],int up[][1001], int m, int n, int leftx, int lefty, int rightx, int righty)
{
if(((righty - lefty) == (left[rightx][righty] - left[rightx][lefty])) and ((left[leftx][righty] - left[leftx][lefty]) ==( righty - lefty)))
{
if(((rightx - leftx) == ( up[rightx][righty] - up[leftx][righty] )) and ((up[rightx][lefty] - up[leftx][lefty]) == rightx - leftx))
{
return (2*(left[leftx][righty] - left[leftx][lefty] + up[rightx][lefty] - up[leftx][lefty] ));
}
}
return 0;
}
void solve(int arr[][1001], int m, int n)
{
int left[1001][1001];
int up[1001][1001];
for(int i=0 ; i<m ;i++)
{
int prev = 1;
for(int j=0 ; j<n ;j++)
{
if(arr[i][j] == 1)
{
left[i][j] = prev;
++prev;
}
else if(arr[i][j] == -1)
{
left[i][j] = -1;
prev =1;
}
}
}
for(int i=0 ; i<n ;i++)
{
int prev = 1;
for(int j=0 ; j<m ;j++)
{
if(arr[j][i] == 1)
{
up[j][i] = prev;
++prev;
}
else if(arr[j][i] == -1)
{
up[j][i] = -1;
prev =1;
}
}
}
int max = 0;
int max_col = 0;
int max_row = 0;
for(int i =0; i < m-1 ; i++)
{
for(int j =0; j<n-1; j++)
{
for(int k = m-1 ; k >i ; k--)
{
for(int l = n-1; l >j ; l--)
{
if(((k-i > max_row) || (l-j > max_col)))
{
int maxi = check(left,up,m,n,i,j,k,l);
if(maxi > max)
{
max = maxi;
max_col = l-j;
max_row = k-i;
}
}
}
}
}
}
cout<<"Dimension = "<<max_col<<"\t"<<max_row<<endl;
}

Resources