Determine if two Trees are Identical - stack

This is the question of Binary Tree. Level: Easy
In the second code, in while loop I just stored the value of popped integer value from stack in int variables and then wrote the condition of if loop. But in first I did not stored them in any variables I directly used them in if condition of while loop. Can anyone please explain why is it creating a difference?
This was my approach, in this if the input trees are 333 and 333 then it gives "no"(trees are not identical).
`
class Solution
{
public void preOrder(Node root,Stack<Integer> stack){
if(root==null){
return ;
}
stack.push(root.data);
preOrder(root.left,stack);
preOrder(root.right,stack);
}
boolean isIdentical(Node root1, Node root2)
{
// Code Here
if(root1==null||root2==null)
return false;
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
preOrder(root1,stack1);
preOrder(root2,stack2);
if(stack1.size()!=stack2.size())
return false;
while(!stack1.isEmpty()&&!stack2.isEmpty()){
if(stack1.pop()!=stack2.pop())
return false;
}
return true;
}
}`
But, in this the same input trees(333 and 333) gave correct output i.e "yes".
` class Solution
{
public void preOrder(Node root,Stack<Integer> stack){
if(root==null){
return ;
}
stack.push(root.data);
preOrder(root.left,stack);
preOrder(root.right,stack);
}
boolean isIdentical(Node root1, Node root2)
{
// Code Here
if(root1==null||root2==null)
return false;
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
preOrder(root1,stack1);
preOrder(root2,stack2);
if(stack1.size()!=stack2.size())
return false;
while(!stack1.isEmpty()&&!stack2.isEmpty()){
int n1 = stack1.pop();
int n2 = stack2.pop();
if(n1!=n2)
return false;
}
return true;
}
}`

Related

Iterating through a linked list using recursion gives me a run time error (stack overflow) on LeetCode

I am new to programming and today I wanted to try out the LeetCode problem 234. Palindrome Linked List:
Given the head of a singly linked list, return true if it is a palindrome or false otherwise.
Example 1:
Input: head = [1,2,2,1]
Output: true
but I couldn't even manage the first problem.
I first tried to convert the linked list to a string and compare like:
String[i] == String[length-i-1]
which worked for small lists but not for the gigantic test list where I got:
Time Limit Exceeded
In my second attempt I used recursion like this:
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode? next;
* ListNode([this.val = 0, this.next]);
* }
*/
class Solution {
bool isPalindrome(ListNode? head) {
ListNode? current = head;
while(current?.next != null)
current = current?.next;
if (current?.val != head?.val)
return false;
else{
current = null;
isPalindrome(head?.next);
}
return true;
}
}
This also works with small lists, but for the test list I get a run time error:
Stack overflow
I wonder where this issue comes from.
Is it due to the maximum number of nested calls? And where can I find the recursion depth of Dart?
Or is there just a way simpler solution for this?
There are several issues with your attempt:
current = null will only set that variable to null. It does not affect the list. If you want to remove the last element from the list, you'll need access to the node that precedes it, and set its next property to null.
The boolean that the recursive call returns is always ignore. Instead execution continues with the return true statement, which will lead to incorrect results (when false was expected).
Before mentioning another problem, here is the correction for your algorithm:
bool isPalindrome(ListNode? head) {
ListNode? current = head;
ListNode? prev = null;
while(current?.next != null) {
prev = current; // follow behind current
current = current?.next;
}
if (current?.val != head?.val)
return false;
else if (prev == null)
return true; // List has only one node
else {
prev?.next = null; // Detach the tail node
return isPalindrome(head?.next); // Return the recursive result!
}
}
This will do the job correctly, but it is too slow. At every level of recursion almost all of the same nodes are iterated again (with that while loop), so for a list with 100 nodes, there are 100+98+96+94+...+2 iterations. In other words, the time complexity of this algorithm is quadratic. You'll need a different idea for the algorithm.
One idea for an efficient algorithm that doesn't require extra O(n) space, is to:
find the middle node of the list. You can for instance first determine the length of the list with a first iteration, and then in a second iteration you can stop half way.
reverse the second half of the list, giving you two shorter lists. Here you could use recursion if you wanted to.
and then compare those two lists node by node.
There are several Q&A on this algorithm, also on this site, so I'll leave that for your further research.
If you cannot make it work, here is a solution (spoiler!):
class Solution {
int listSize(ListNode? head) {
int size = 0;
while(head?.next != null) {
head = head?.next;
size++;
}
return size;
}
ListNode? nodeAt(ListNode? head, int index) {
while(head?.next != null && index > 0) {
head = head?.next;
index--;
}
return index == 0 ? head : null;
}
ListNode? reverse(ListNode? head) {
ListNode? prev = null;
ListNode? next;
while (head != null) {
next = head.next;
head.next = prev;
prev = head;
head = next;
}
return prev;
}
bool isEqual(ListNode? head1, ListNode? head2) {
// Only compares the nodes that both lists have:
while (head1 != null && head2 != null) {
if (head1.val != head2.val) return false;
head1 = head1.next;
head2 = head2.next;
}
return true;
}
bool isPalindrome(ListNode? head) {
return isEqual(head, reverse(nodeAt(head, listSize(head) >> 1)));
}
}
I can't quite understand your recursion solution without pointers. I solved it using a list. It is not the best solution but is simple.
// Definition for singly-linked list.
// class ListNode {
// int val;
// ListNode? next;
// ListNode([this.val = 0, this.next]);
// }
class Solution {
bool isPalindrome(ListNode? head) {
List<int> stack = [];
ListNode? p = head;
while (p != null) {
stack.add(p.val);
p = p.next;
}
print(stack);
bool isP = true;
while(head!.next!=null&&isP){
var a = stack.removeLast();
print('removed $a');
print('head val ${head.val}');
isP = head.val==a;
head=head.next!;
}
return isP;
}
}
The problem with your solution is
After a while loop current is rightmost node in the list
while (current?.next != null) {
current = current?.next;
}
comparing leftmost and rightmost node of LinkedList
if (current?.val != head?.val)
return false;
Start over with head shifted one place to the right
else {
current = null;
isPalindrome(head?.next);
}
But current is still rightmost node after a while loop
while (current?.next != null) {
current = current?.next;
}
And this will return false
if (current?.val != head?.val)
{
return false;
}
After second recursion program exits returning true

How to print Map in dart?

I know how to print map using foreach() method
var x = {1:'One',2:'Two',3:'Three',4:'Four',5:'Five'};
x.foreach((i,j){
print(i);
print(j);
});
and using normal for loop
other methods to print map ?
You can also directly print the map:
void main() {
var x = {1:'One',2:'Two',3:'Three',4:'Four',5:'Five'};
print(x);
}
The result will be pretty neat:
{1: One, 2: Two, 3: Three, 4: Four, 5: Five}
You will find the implementation of mapToString here.
static String mapToString(Map<Object?, Object?> m) {
// Reuses the list in IterableBase for detecting toString cycles.
if (_isToStringVisiting(m)) {
return '{...}';
}
var result = StringBuffer();
try {
_toStringVisiting.add(m);
result.write('{');
bool first = true;
m.forEach((Object? k, Object? v) {
if (!first) {
result.write(', ');
}
first = false;
result.write(k);
result.write(': ');
result.write(v);
});
result.write('}');
} finally {
assert(identical(_toStringVisiting.last, m));
_toStringVisiting.removeLast();
}
return result.toString();
}

Stream Data Calculation In Flux

The following code illustrates a logic I need in a Spring Reactive project:
Inputs:
var period = 3;
int [] inArr = {2, 4, 6, 7, 9, 11, 13, 16, 17, 18, 20, 22 };
Calculation:
var upbond = inArr[0] + period;
var count =0;
List<Integer> result = new ArrayList();
for(int a: inArr){
if(a <= upbond){
count++;
}else{
result.add(count);
count = 1;
upbond += period;
}
}
result.add(count);
System.out.println(Arrays.toString(result.toArray()));
The data source of the sorted integers is the Flux from DB where it shall continually fetch data once a new suitable data is written into the DB. And the result shall be a stream that is sending out to another node through RSocket (by the request-stream communication mode).
After some online searching on Reactor, including some tutorials, I still can't figure out how to write the logic in the Flux fashion. The difficulty I have is that those calculations on data defined outside of the loop.
How shall I approach it in the Reactor?
The scan() variant that lets you use a separately typed accumulator is your friend here.
I'd approach this with a separate State class:
public class State {
private int count;
private Optional<Integer> upbond;
private Optional<Integer> result;
public State() {
this.count = 0;
this.upbond = Optional.empty();
this.result = Optional.empty();
}
public State(int count, int upbond) {
this.count = count;
this.upbond = Optional.of(upbond);
this.result = Optional.empty();
}
public State(int count, int upbond, int result) {
this.count = count;
this.upbond = Optional.of(upbond);
this.result = Optional.of(result);
}
public int getCount() {
return count;
}
public Optional<Integer> getUpbond() {
return upbond;
}
public Optional<Integer> getResult() {
return result;
}
}
...and then use scan() to build up the state element by element:
sourceFlux
.concatWithValues(0)
.scan(new State(), (state, a) ->
a <= state.getUpbond().orElse(a + period) ?
new State(state.getCount() + 1, state.getUpbond().orElse(a + period)) :
new State(1, state.getUpbond().orElse(a + period) + period, state.getCount())
)
.windowUntil(s -> s.getResult().isPresent())
.flatMap(f -> f.reduce((s1, s2) -> s1.getResult().isPresent()?s1:s2).map(s -> s.getResult().orElse(s.getCount() - 1)))
Aside: The concatWithValues() / windowUntil() / flatMap() bits are there to handle the last element - there's probably a cleaner way of achieving that, if I think of it I'll edit the answer.
I think scan is definitely the right tool here, combined with a stateful class, although my approach would be slightly different than Michaels.
Accumulator:
class UpbondAccumulator{
final Integer period;
Integer upbond;
Integer count;
Boolean first;
Queue<Integer> results;
UpbondAccumulator(Integer period){
this.period = period;
this.count = 0;
this.upbond = 0;
this.results = new ConcurrentLinkedQueue<>();
this.first = true;
}
//Logic is inside accumulator, since accumulator is the only the only thing
//that needs it. Allows reuse of accumulator w/o code repetition
public UpbondAccumulator process(Integer in){
//If impossible value
//Add current count to queue and return
//You will have to determine what is impossible
//Since we concat this value on the end of flux
//It will signify the end of processing
//And emit the last count
if(in<0){
results.add(count);
return this;
}
//If first value
//Do stuff outside loop
if(this.first) {
upbond = in + period;
first=false;
}
//Same as your loop
if(in <= upbond)
count++;
else {
results.add(count);
count = 1;
upbond += period;
}
//Return accumulator
//This could be put elsewhere since it isn't
//Immediately obvious that `process` should return
//the object but is simpler for example
return this;
}
public Mono<Integer> getResult() {
//Return mono empty if queue is empty
//Otherwise return queued result
return Mono.justOrEmpty(results.poll());
}
}
Usage:
dbFlux
//Concat with impossible value
.concatWithValues(-1)
//Create accumulator, process value and return
.scan(new UpbondAccumulator(period), UpbondAccumulator::process)
//Get results, note if there are no results, this will be empty
//meaning it isn't passed on in chain
.flatMap(UpbondAccumulator::getResult)
Following comment from Michael here is an immutable approach
Accumulator:
public class UpbondAccumulator{
public static UpbondState process(int period,Integer in,UpbondState previous){
Integer upbond = previous.getUpbond().orElse(in + period);
int count = previous.getCount();
if(in<0) return new UpbondState(upbond, count, count);
if(in <= upbond) return new UpbondState(upbond,count + 1 , null);
return new UpbondState(upbond + period, 1, count);
}
}
State object:
public class UpbondState {
private final Integer upbond;
private final int count;
private final Integer result;
public UpbondState() {
this.count = 0;
this.upbond = null;
this.result = null;
}
public UpbondState(Integer upbond, int count,Integer result) {
this.upbond = upbond;
this.count = count;
this.result = result;
}
public int getCount() { return count; }
public Optional<Integer> getUpbond() { return Optional.ofNullable(upbond); }
public Integer getResult() { return result; }
public boolean hasResult() { return result!=null; }
}
Usage:
dbFlux
.concatWithValues(-1)
.scan(new UpbondState(),
(prev, in) -> UpbondAccumulator.process(period,in,prev))
//Could be switched for Optional, but would mean one more map
//+ I personally think makes logic less clear in this scenario
.filter(UpbondState::hasResult)
.map(UpbondState::getResult)

I have no idea why i have error Exception in thread "main" java.lang.NullPointerException

I tried to use reverseBystack, reverseBylink and remove.. but I don't know why when i use these functions, it has error like this.
Exception in thread "main" java.lang.NullPointerException
at LinkedQueue$Node.access$200(LinkedQueue.java:44)
at LinkedQueue.reverseBylink(LinkedQueue.java:185)
at LinkedQueue.main(LinkedQueue.java:238)
void reverseByStack() - This method reverses the order of the items in the linked list (first
becomes last and last becomes first) using a stack data strucenter code hereture`
• void reverseByLinks() - This method also reverses the order of the items in the linked list.
It should not create a new list or use a stack. It should only reverse the order of the nodes by
modifying the next values for each node in the list.
• int remove(Item item) - This method scans the queue for occurrences of item and removes
them from the queue. It returns the number of items deleted from the queue.
these are what i want to make.
enter code here public class LinkedQueue<Item> implements Iterable<Item> {
private int N; // number of elements on queue
private Node first; // beginning of queue
private Node last; // end of queue
// helper linked list class
private class Node {
private Item item;
private Node next;
}
public LinkedQueue() {
first = null;
last = null;
N = 0;
assert check();
}
public boolean isEmpty() {
return first == null;
}
public int size() {
return N;
}
public Item peek() {
if (isEmpty()) throw new NoSuchElementException("Queue
underflow");
return first.item;
}
public void enqueue(Item item) {
Node oldlast = last;
last = new Node();
last.item = item;
last.next = null;
if (isEmpty()) first = last;
else oldlast.next = last;
N++;
assert check();
}
public Item dequeue() {
if (isEmpty()) throw new NoSuchElementException("Queue
underflow");
Item item = first.item;
first = first.next;
N--;
if (isEmpty()) last = null; // to avoid loitering
assert check();
return item;
}
public String toString() {
StringBuilder s = new StringBuilder();
for (Item item : this)
s.append(item + " ");
return s.toString();
}
private boolean check() {
if (N == 0) {
if (first != null) return false;
if (last != null) return false;
}
else if (N == 1) {
if (first == null || last == null) return false;
if (first != last) return false;
if (first.next != null) return false;
}
else {
if (first == last) return false;
if (first.next == null) return false;
if (last.next != null) return false;
// check internal consistency of instance variable N
int numberOfNodes = 0;
for (Node x = first; x != null; x = x.next) {
numberOfNodes++;
}
if (numberOfNodes != N) return false;
// check internal consistency of instance variable last
Node lastNode = first;
while (lastNode.next != null) {
lastNode = lastNode.next;
}
if (last != lastNode) return false;
}
return true;
}
void reverseBystack(){
Stack<Item> s = new Stack<>();
Item item;
while (s.isEmpty() != true){
item = dequeue();
s.push(item);
}
while(s.isEmpty() != true){
item = s.pop();
enqueue(item);
}
}
void reverseBylink() {
Node prev = null;
Node current = this.first;
Node next = null;
while (current != null) {
next = current.next;
current.next = prev;
prev = current;
current = next;
}
prev.next = current.next;
}
int remove(Item item){
Node cur = first;
Node prev = last;
while(cur != null) {
if(cur.item.equals(item))
System.out.println(cur.item);
}
cur = cur.next;
prev = cur.next;
return 0;
}
public Iterator<Item> iterator() {
return new ListIterator();
}
private class ListIterator implements Iterator<Item> {
private Node current = first;
public boolean hasNext() { return current != null;
}
public void remove() { throw new
UnsupportedOperationException(); }
public Item next() {
if (!hasNext()) throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
/**
* Unit tests the <tt>LinkedQueue</tt> data type.
*/
public static void main(String[] args) {
LinkedQueue<String> q = new LinkedQueue<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) q.reverseBylink();
else if (!q.isEmpty()) StdOut.print(q.dequeue() + " ");
}
StdOut.println("(" + q.size() + " left on queue)");
}
}

How do I create a blank Future in Dart + how do I return a future currently in progress?

I'm trying to create a server-side Dart class that performs various data-related tasks. All of these tasks rely on the database having been first initialized. The problem is that the init of the database happens asynchronously (returns a Future). I first tried to put the init code into the constructor, but have given up on this approach as it seems to not be viable.
I am now attempting to figure out how to force the DB initialization as a first step in any method call that accesses data. So in other words, when attemptLogin() is called below, I'd like to first check if the DB has been initialized and initialize it if necessary.
However, there are two obstacles. If the database hasn't been initialized, the code is straightforward - initialize the db, then use the then() method of the returned future to do the rest of the function. If the db is not yet initialized, what do I attach my then() method to?
Second related question is what happens when a database is currently being initialized but this process is not yet complete? How can I pull in and return this "in-progress" Future?
This is the basic gist of the code I'm trying to wrangle:
class DataManager {
bool DbIsReady = false;
bool InitializingDb = false;
Db _db;
Future InitMongoDB() {
print("Initializing MongoDB");
InitializingDb = true;
_db = new Db("mongodb://127.0.0.1/test");
return _db.open().then((_) {
DbIsReady = true;
InitializingDb = false;
});
}
Future<List> attemptLogin(String username, String password) {
Future firstStep;
if ((!DbIsReady) && (!InitializingDb) {
Future firstStep = InitMongoDB()
}
else if (InitializingDb) {
// Need to return the InitMongoDB() Future that's currently running, but how?
}
else {
// How do I create a blank firstStep here?
}
return firstStep.then((_) {
users = _db.collection("users");
return // ... rest of code cut out for clarity
});
}
}
Thanks in advance for your help,
Greg
Just return
return new Future<bool>.value(true);
// or any other value instead of `true` you want to return.
// or none
// return new Future.value();
Just keep the future alive:
class DataManager {
Future _initializedDb;
Future initMongoDb() { ... }
Future<List> attemptLogin(String username, String password) {
if (_initializedDb == null) {
_initializedDb = initMongoDB();
}
return _initializedDb.then((db) {
users = db.collection("users");
return // ... rest of code cut out for clarity
});
}
}
You might need to pay attention for the error-case. It's up to you if you want to deal with errors in the initMongoDB or after it.
One of the possible solutions:
import "dart:async";
void main() {
var dm = new DataManager();
var selectOne = dm.execute("SELECT 1");
var selectUsers = dm.execute("SELECT * FROM users");
var users = selectOne.then((result) {
print(result);
return selectUsers.then((result) {
print(result);
});
});
users.then((result) {
print("Goodbye");
});
}
class Event {
List<Function> _actions = new List<Function>();
bool _raised = false;
void add(Function action) {
if (_raised) {
action();
} else {
_actions.add(action);
}
}
void raise() {
_raised = true;
_notify();
}
void _notify() {
if (_actions.isEmpty) {
return;
}
var actions = _actions.toList();
_actions.clear();
for (var action in actions) {
action();
}
}
}
class DataManager {
static const int _STATE_NOT_INITIALIZED = 1;
static const int _STATE_INITIALIZING = 2;
static const int _STATE_READY = 3;
Event _initEvent = new Event();
int _state = _STATE_NOT_INITIALIZED;
Future _init() {
if (_state == _STATE_NOT_INITIALIZED) {
_state = _STATE_INITIALIZING;
print("Initializing...");
return new Future(() {
print("Initialized");
_state = _STATE_READY;
_initEvent.raise();
});
} else if (_state == _STATE_INITIALIZING) {
print("Waiting until initialized");
var completer = new Completer();
_initEvent.add(() => completer.complete());
return completer.future;
}
return new Future.value();
}
Future execute(String query, [Map arguments]) {
return _init().then((result) {
return _execute(query, arguments);
});
}
Future _execute(String query, Map arguments) {
return new Future.value("query: $query");
}
}
Output:
Initializing...
Waiting until initialized
Initialized
query: SELECT 1
query: SELECT * FROM users
Goodbye
I think that exist better solution but this just an attempt to answer on your question (if I correctly understand you).
P.S. EDITED at 11 July 2014
Slightly modified (with error handling) example.
import "dart:async";
void main() {
var dm = new DataManager();
var selectOne = dm.execute("SELECT 1");
var selectUsers = dm.execute("SELECT * FROM users");
var users = selectOne.then((result) {
print(result);
return selectUsers.then((result) {
print(result);
});
});
users.then((result) {
print("Goodbye");
});
}
class DataManager {
static const int _STATE_NOT_INITIALIZED = 1;
static const int _STATE_INITIALIZING = 2;
static const int _STATE_READY = 3;
static const int _STATE_FAILURE = 4;
Completer _initEvent = new Completer();
int _state = _STATE_NOT_INITIALIZED;
Future _ensureInitialized() {
switch (_state) {
case _STATE_NOT_INITIALIZED:
_state = _STATE_INITIALIZING;
print("Initializing...");
new Future(() {
print("Initialized");
_state = _STATE_READY;
// throw null;
_initEvent.complete();
}).catchError((e, s) {
print("Failure");
_initEvent.completeError(e, s);
});
break;
case _STATE_INITIALIZING:
print("Waiting until initialized");
break;
case _STATE_FAILURE:
print("Failure detected");
break;
default:
print("Aleady intialized");
break;
}
return _initEvent.future;
}
Future execute(String query, [Map arguments]) {
return _ensureInitialized().then((result) {
return _execute(query, arguments);
});
}
Future _execute(String query, Map arguments) {
return new Future.value("query: $query");
}
}
For those that are still wondering how to create a blank Future in Dart and later complete them, you should use the Completer class like in the next example.
class AsyncOperation {
final Completer _completer = new Completer();
Future<T> doOperation() {
_startOperation();
return _completer.future; // Send future object back to client.
}
// Something calls this when the value is ready.
void finishOperation(T result) {
_completer.complete(result);
}
// If something goes wrong, call this.
void _errorHappened(error) {
_completer.completeError(error);
}
}
Future<Type> is non nullable in Dart, meaning that you have to initialize it to a value. If you don't, Dart throws the following error:
Error: Field should be initialized because its type 'Future<Type>' doesn't allow null.
To initialize a Future<Type>, see the following example:
Future<String> myFutureString = Future(() => "Future String");
Here "Future String" is a String and so the code above returns an instance of Future<String>.
So coming to the question of how to create a blank/empty Future, I used the following code for initializing an empty Future List.
Future<List> myFutureList = Future(() => []);
I found this link to be quite useful in understanding Futures in Flutter and Dart: https://meysam-mahfouzi.medium.com/understanding-future-in-dart-3c3eea5a22fb

Resources