Given two strings s and t, determine length of shortest string z such that z is a subsequence of s and not a subsequence of t.
example :
s :babab,
t :babba
sol :
3 (aab)
not looking for copy pastable code, please if anybody can help with intution for solving this.
thanks a lot !
Here you go. I created on IEnumarable method which gives back all possible combinations. This is compared with t. I optimized the solution to loop only once over the not match String t.
using System;
using System.Collections.Generic;
namespace GuessTheNumber
{
public class Element:IComparable<Element>
{
public string Seq { get; set; }
public int Id { get; set; }
public int CompareTo(Element other)
{
return this.Seq.CompareTo(other.Seq);
}
}
class Program
{
static void Main(string[] args)
{
string s = "babab";
string t = "babba";
string z = ShortestUncommonSuqsequence(s, t);
}
static public string ShortestUncommonSuqsequence(string SubSequenceOf, string NotSubSequenceOf)
{
var uniqueSeq = new SortedList<Element, int>();
uniqueSeq.Add(new Element() { Seq = "", Id = -1 }, -1);
foreach (Element oneSequence in GetNextUniqueSequences(uniqueSeq, SubSequenceOf))
{
int index = oneSequence.Id + 1;
while (index < NotSubSequenceOf.Length)
{
char NotChar = NotSubSequenceOf[index];
if (oneSequence.Seq[oneSequence.Seq.Length - 1] == NotChar) break;
index++;
}
if (index == NotSubSequenceOf.Length)
{
return oneSequence.Seq;
}
else
{
oneSequence.Id = index;
}
}
return null;
}
static public IEnumerable<Element> GetNextUniqueSequences(SortedList<Element, int> UniqueSeq, string Input)
{
SortedList<Element, int> results = new SortedList<Element, int>();
foreach (var prevResult in UniqueSeq)
{
for (int i = 0; i < Input.Length; i++)
{
if (prevResult.Value < prevResult.Key.Seq.Length + i)
{
string nextStr = prevResult.Key.Seq + Input[i].ToString();
Element newElem = new Element() { Seq = nextStr, Id = prevResult.Key.Id };
if (!results.Keys.Contains(newElem))
{
results.Add(newElem, prevResult.Key.Seq.Length + i);
yield return newElem;
}
}
}
}
if (Input.Length > 1)
{
foreach (Element res in GetNextUniqueSequences(results, Input.Substring(1)))
{
yield return res;
}
}
}
}
}
Related
Given Parent Array Such that parent[i]=j where j is the parent and Value array . Need to Find Best possible sum.
Root node will have -1 as parent.
Best Possible sum is maximum sum in one of the tree paths.
Ex)
Integer[] parent = new Integer[] { -1, 0, 0, 2, 3 };
Integer[] values = new Integer[] { 0, 4, 6, -11, 3 };
(0/0)----(1/4)
|
|
(2/6)
|
|
(3/-11)
|
|
(4/3)
Maximum sum here would be 6+0+4=10 for path 2-->0-->1.
I have tried solving it the dfs way. But not sure if it works for all cases. Below is my code. It gives all possible sum. we can take out max from that.
package com.programs.algo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class BestPossibleSum {
static class Node<T> {
T label;
T data;
List<Node<T>> nodes;
}
public static void main(String[] args) {
Integer[] parent = new Integer[] { -1, 0, 0, 1, 1, 3, 5 };
Integer[] values = new Integer[] { 0, 4, 6, -11, 3, 10, 11 };
List<Integer> list1 = new ArrayList<>(Arrays.asList(parent));
List<Integer> list2 = new ArrayList<>(Arrays.asList(values));
bestPossibleSum(list1, list2);
}
static List<Node<Integer>> tree = new ArrayList<>();
private static void bestPossibleSum(List<Integer> list1, List<Integer> list2) {
int adj[][] = new int[list1.size()][list1.size()];
createTree(list1, list2, adj);
List<Integer> traversedNodes = new ArrayList<>();
List<Integer> sumOfraversedNodes = new ArrayList<>();
for (int i = 0; i < adj.length; i++) {
dfs(tree.get(i), traversedNodes, sumOfraversedNodes);
traversedNodes.clear();
}
System.out.println(sumOfraversedNodes);
}
private static void dfs(Node<Integer> tree, List<Integer> traversedNodes, List<Integer> sums) {
if (!traversedNodes.contains(tree.label)) {
traversedNodes.add(tree.label);
sums.add(getSum(traversedNodes));
for (Node<Integer> child : tree.nodes) {
dfs(child, traversedNodes, sums);
}
}
}
private static Integer getSum(List<Integer> traversedNodes) {
System.out.println(traversedNodes);
return traversedNodes.stream().reduce(0, Integer::sum);
}
private static void createTree(List<Integer> parent, List<Integer> values, int[][] adj) {
for (int i = 0; i < parent.size(); i++) {
Node<Integer> node = new Node<>();
node.label = i;
node.data = values.get(i);
node.nodes = new ArrayList<>();
tree.add(i, node);
}
for (int i = 0; i < parent.size(); i++) {
if (parent.get(i) != -1) {
adj[parent.get(i)][i] = 1;
adj[i][parent.get(i)] = 1;
tree.get(parent.get(i)).nodes.add(tree.get(i));
}
}
tree.forEach(t -> {
System.out.println(t.label);
System.out.println(t.nodes.stream().map(m -> m.label).collect(Collectors.toList()));
});
// System.out.println(Arrays.deepToString(adj));
}
}
I would divide your question to 2 different issues:
Build tree from your data
Find the max sum
I wrote the code in PHP but you can convert it to any language you need (my JAVA skill are bit rusty...)
Build the Tree:
$parent = array( -1, 0, 0, 2, 3 );
$values = array(0, 4, 6, -11, 3 );
function getNode($id, $data) {
return array("id" => $id, "data" => $data, "childs" => array());
}
function addToTree($node, &$root, $parentsId) {
if ($parentsId == -1)
$root = $node;
else if ( $root["id"] == $parentsId)
$root["childs"][] = $node;
else
foreach($root["childs"] as &$child)
addToTree($node, $child, $parentsId);
}
$root = null;
for($i = 0; $i < count($parent); $i++) {
addToTree(getNode($i, $values[$i]), $root, $parent[$i]);
}
Now root if contain you "tree-like" data. Notice this code works only if the nodes given at the right order and it cannot support multi root (assume tree and not forest)
Find max path:
function maxPath($node) {
$sum = $node["data"];
foreach($node["childs"] as $child) {
$s = maxPath($child);
if ($s > 0) // if its not positive then don't take it
$sum += $s;
}
return $sum;
}
This recursive function will get your max-sum-path. Notice this will allow multi-child per node and also the path can have star-shape.
Posting Java code considering it as tree with left and right nodes.
https://www.geeksforgeeks.org/construct-a-binary-tree-from-parent-array-representation/
https://www.geeksforgeeks.org/find-maximum-path-sum-in-a-binary-tree/
private static int maxSum(Node<Integer> btree, Result result) {
if (btree == null)
return 0;
int l = maxSum(btree.left, result);
int r = maxSum(btree.right, result);
System.out.println(l + " " + r + " " + btree.data);
int maxSingle = Math.max(Math.max(l, r) + btree.label, btree.label);
int maxTop = Math.max(l + r + btree.label, maxSingle);
result.val = Math.max(maxTop, result.val);
return maxSingle;
}
private static Node<Integer> createBinaryTree(Integer[] parent, Node<Integer> root) {
Map<Integer, Node<Integer>> map = new HashMap<>();
for (int i = 0; i < parent.length; i++) {
map.put(i, new Node<>(i));
}
for (int i = 0; i < parent.length; i++) {
if (parent[i] == -1) {
root = map.get(i);
} else {
Node<Integer> par = map.get(parent[i]);
Node<Integer> child = map.get(i);
if (par.left == null) {
par.left = child;
} else {
par.right = child;
}
}
}
return root;
}
1 . convert the given parent array into graph with the following steps :
unordered_map<int,vector<pair<int,int>>> graph;
for(int i=0;i<n;i++){
if(parents[i]!=-1){
graph[parents[i]].push_back({i,values[i]});
graph[i].push_back({parents[i],values[parents[i]]});
}
}
2.apply DFS on each node and check the maximum Path Sum
vector<bool> vis(n,false);
int res=0;
for(int i=0;i<n;i++){
vis.clear();
dfs(i,vis,mp,values,res);
}
DFS function
void dfs(int src,vector&vis,unordered_map<int,
vector<pair<int,int>>>&graph,vector<int>&values,int res){
res+=values[src];
ans=max(ans,res);
vis[src]=true;
for(int i=0;i<graph[src].size();i++){
if(!vis[graph[src][i].first]){
dfs(graph[src][i].first,vis,graph,values,res);
}
}
vis[src]=false;
}
C++ code :
#include<bits/stdc++.h>
using namespace std;
int ans=INT_MIN;
void dfs(int src,vector<bool>&vis,unordered_map<int,
vector<pair<int,int>>>&graph,vector<int>&values,int res){
res+=values[src];
ans=max(ans,res);
vis[src]=true;
for(int i=0;i<graph[src].size();i++){
if(!vis[graph[src][i].first]){
dfs(graph[src][i].first,vis,graph,values,res);
}
}
vis[src]=false;
}
int maxPathSum(vector<int>&parents,vector<int>&values){
int n=parents.size();
unordered_map<int,vector<pair<int,int>>> mp;
for(int i=0;i<n;i++){
if(parents[i]!=-1){
mp[parents[i]].push_back({i,values[i]});
mp[i].push_back({parents[i],values[parents[i]]});
}
}
vector<bool> vis(n,false);
int res=0;
for(int i=0;i<n;i++){
vis.clear();
dfs(i,vis,mp,values,res);
}
return ans;
}
int main(){
vector<int> parent = {-1,0,0,2,3}; //{-1,0,1,2,0};
vector<int> values = {0,4,6,-11,3}; //{-2,10,10,-3,10};
cout<<maxPathSum(parent,values)<<endl;
return 0;
}
Today I got this problem in One of the company's hackerrank test.
Here is my solution. All test cases have been passed successfully
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.regex.*;
import java.util.stream.*;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
class Result {
/*
* Complete the 'bestSumDownwardTreePath' function below.
*
* The function is expected to return an INTEGER.
* The function accepts following parameters:
* 1. INTEGER_ARRAY parent
* 2. INTEGER_ARRAY values
*/
static int bestPath = Integer.MIN_VALUE;
public static int bestSumDownwardTreePath(List<Integer> parent, List<Integer> values) {
if(parent.size() == 1) return values.get(0);
Map<Integer, List<Integer>> tree = new HashMap<>();
for(int i = 1; i < parent.size(); i++) {
List<Integer> temp = tree.getOrDefault(parent.get(i), null);
if(temp == null) {
temp = new ArrayList<>();
temp.add(i);
tree.put(parent.get(i), temp);
}
else {
temp.add(i);
}
}
findBestSum(parent, values, tree, 0, 0);
return bestPath;
}
public static void findBestSum(List<Integer> parent, List<Integer> values,
Map<Integer, List<Integer>> tree, int root, int sum) {
sum = sum + values.get(root);
bestPath = Math.max(bestPath, sum);
sum = Math.max(0, sum);
if(tree.get(root) == null) return;
for(Integer child: tree.get(root)) {
findBestSum(parent, values, tree, child, sum);
}
}
}
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
int parentCount = Integer.parseInt(bufferedReader.readLine().trim());
List<Integer> parent = IntStream.range(0, parentCount).mapToObj(i -> {
try {
return bufferedReader.readLine().replaceAll("\\s+$", "");
} catch (IOException ex) {
throw new RuntimeException(ex);
}
})
.map(String::trim)
.map(Integer::parseInt)
.collect(toList());
int valuesCount = Integer.parseInt(bufferedReader.readLine().trim());
List<Integer> values = IntStream.range(0, valuesCount).mapToObj(i -> {
try {
return bufferedReader.readLine().replaceAll("\\s+$", "");
} catch (IOException ex) {
throw new RuntimeException(ex);
}
})
.map(String::trim)
.map(Integer::parseInt)
.collect(toList());
int result = Result.bestSumDownwardTreePath(parent, values);
bufferedWriter.write(String.valueOf(result));
bufferedWriter.newLine();
bufferedReader.close();
bufferedWriter.close();
}
}
I'm not sure where to start, but this is messy. Basically I need to write an Insertion Sort method for singly linked list - which causes enough problems, because usually for Insertion Sort - you're supposed to go through array/list elements backwards - which implementing into a singly linked list seems pointless, because the point of it - is that you're only capable of going forwards in the list and in addition to that -> I need to execute "swap" operations externally, which I do not completely understand how to perform that while using list structure.
This is my ArrayClass and Swap method that I used:
class MyFileArray : DataArray
{
public MyFileArray(string filename, int n, int seed)
{
double[] data = new double[n];
length = n;
Random rand = new Random(seed);
for (int i = 0; i < length; i++)
{
data[i] = rand.NextDouble();
}
if (File.Exists(filename)) File.Delete(filename);
try
{
using (BinaryWriter writer = new BinaryWriter(File.Open(filename,
FileMode.Create)))
{
for (int j = 0; j < length; j++)
writer.Write(data[j]);
}
}
catch (IOException ex)
{
Console.WriteLine(ex.ToString());
}
}
public FileStream fs { get; set; }
public override double this[int index]
{
get
{
Byte[] data = new Byte[8];
fs.Seek(8 * index, SeekOrigin.Begin);
fs.Read(data, 0, 8);
double result = BitConverter.ToDouble(data, 0);
return result;
}
}
public override void Swap(int j, double a)
{
Byte[] data = new Byte[16];
BitConverter.GetBytes(a).CopyTo(data, 0);
fs.Seek(8 * (j + 1), SeekOrigin.Begin);
fs.Write(data, 0, 8);
}
}
And this is my Insertion Sort for array:
public static void InsertionSort(DataArray items)
{
double key;
int j;
for (int i = 1; i < items.Length; i++)
{
key = items[i];
j = i - 1;
while (j >= 0 && items[j] > key)
{
items.Swap(j, items[j]);
j = j - 1;
}
items.Swap(j, key);
}
}
Now I somehow have to do the same exact thing - however using Singly Linked List, I'm given this kind of class to work with (allowed to make changes):
class MyFileList : DataList
{
int prevNode;
int currentNode;
int nextNode;
public MyFileList(string filename, int n, int seed)
{
length = n;
Random rand = new Random(seed);
if (File.Exists(filename)) File.Delete(filename);
try
{
using (BinaryWriter writer = new BinaryWriter(File.Open(filename,
FileMode.Create)))
{
writer.Write(4);
for (int j = 0; j < length; j++)
{
writer.Write(rand.NextDouble());
writer.Write((j + 1) * 12 + 4);
}
}
}
catch (IOException ex)
{
Console.WriteLine(ex.ToString());
}
}
public FileStream fs { get; set; }
public override double Head()
{
Byte[] data = new Byte[12];
fs.Seek(0, SeekOrigin.Begin);
fs.Read(data, 0, 4);
currentNode = BitConverter.ToInt32(data, 0);
prevNode = -1;
fs.Seek(currentNode, SeekOrigin.Begin);
fs.Read(data, 0, 12);
double result = BitConverter.ToDouble(data, 0);
nextNode = BitConverter.ToInt32(data, 8);
return result;
}
public override double Next()
{
Byte[] data = new Byte[12];
fs.Seek(nextNode, SeekOrigin.Begin);
fs.Read(data, 0, 12);
prevNode = currentNode;
currentNode = nextNode;
double result = BitConverter.ToDouble(data, 0);
nextNode = BitConverter.ToInt32(data, 8);
return result;
}
To be completely honest - I'm not sure neither how I'm supposed to implement Insertion Sort nor How then translate it into an external sort. I've used this code for not external sorting previously:
public override void InsertionSort()
{
sorted = null;
MyLinkedListNode current = headNode;
while (current != null)
{
MyLinkedListNode next = current.nextNode;
sortedInsert(current);
current = next;
}
headNode = sorted;
}
void sortedInsert(MyLinkedListNode newnode)
{
if (sorted == null || sorted.data >= newnode.data)
{
newnode.nextNode = sorted;
sorted = newnode;
}
else
{
MyLinkedListNode current = sorted;
while (current.nextNode != null && current.nextNode.data < newnode.data)
{
current = current.nextNode;
}
newnode.nextNode = current.nextNode;
current.nextNode = newnode;
}
}
So if someone could maybe give some kind of tips/explanations - or maybe if you have ever tried this - code examples how to solve this kind of problem, would be appreciated!
I actually have solved this fairly recently.
Here's the code sample that you can play around with, it should work out of the box.
public class SortLinkedList {
public static class LinkListNode {
private Integer value;
LinkListNode nextNode;
public LinkListNode(Integer value, LinkListNode nextNode) {
this.value = value;
this.nextNode = nextNode;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public LinkListNode getNextNode() {
return nextNode;
}
public void setNextNode(LinkListNode nextNode) {
this.nextNode = nextNode;
}
#Override
public String toString() {
return this.value.toString();
}
}
public static void main(String...args) {
LinkListNode f = new LinkListNode(12, null);
LinkListNode e = new LinkListNode(11, f);
LinkListNode c = new LinkListNode(13, e);
LinkListNode b = new LinkListNode(1, c);
LinkListNode a = new LinkListNode(5, b);
print(sort(a));
}
public static void print(LinkListNode aList) {
LinkListNode iterator = aList;
while (iterator != null) {
System.out.println(iterator.getValue());
iterator = iterator.getNextNode();
}
}
public static LinkListNode sort(LinkListNode aList){
LinkListNode head = new LinkListNode(null, aList);
LinkListNode fringePtr = aList.getNextNode();
LinkListNode ptrBeforeFringe = aList;
LinkListNode findPtr;
LinkListNode prev;
while(fringePtr != null) {
Integer valueToInsert = fringePtr.getValue();
findPtr = head.getNextNode();
prev = head;
while(findPtr != fringePtr) {
System.out.println("fringe=" + fringePtr);
System.out.println(findPtr);
if (valueToInsert <= findPtr.getValue()) {
LinkListNode tmpNode = fringePtr.getNextNode();
fringePtr.setNextNode(findPtr);
prev.setNextNode(fringePtr);
ptrBeforeFringe.setNextNode(tmpNode);
fringePtr = ptrBeforeFringe;
break;
}
findPtr = findPtr.getNextNode();
prev = prev.getNextNode();
}
fringePtr = fringePtr.getNextNode();
if (ptrBeforeFringe.getNextNode() != fringePtr) {
ptrBeforeFringe = ptrBeforeFringe.getNextNode();
}
}
return head.getNextNode();
}
}
From a high level, what you are doing is you are keeping track of a fringe ptr, and you are inserting a node s.t. the it is in the correct spot in the corresponding sublist.
For instance, suppose I have this LL.
3->2->5->4
The first iteration, I have fringePtr at 2, and I want to insert 2 somewhere in the sublist that's before the fringe ptr, so I basically traverse starting from head going to the fringe ptr until the value is less than the current value. I also have a previous keeping track of the previous ptr (to account for null, I have a sentinel node at the start of my traversal so I can insert it at the head).
Then, when I see that it's less than the current, I know I need to insert it next to the previous, so I have to:
use a temporary ptr to keep track of my previous's current next.
bind previuos's next to my toInsert node.
bind my toInsert node's next to my temp node.
Then, to continue, you just advance your fringe ptr and try again, basically building up a sublist that is sorted as you move along until fringe hits the end.
i.e. the iterations will look like
1. 3->2->5->4
^
2. 2->3->5->4
^
3. 2->3->5->4
^
4. 2->3->4->5 FIN.
Hi I know it's bascially a hash table, but since it ask for iterate time is O(number of elements) rather than O(size of array). Any thoughts?
Detail requirements:
Use array-like data strcutre only
Achieve the below time compleixty:
Add:O(1) time
Delete: O(1) time
Search: O(1) time
Clear: O(1) time
Iterate: O(number of elements)
Below is my solution:
public class myDS
{
public LinkedList<int> idxArr;
public HashEntry[] eleArr;
private int capacity = 251; //Some random prime number
//Constructor
public myDS()
{
eleArr = new HashEntry[capacity];
/*for (int i = 0; i < capacity; i++) Not sure if we need it.
{
eleArr[i] = null;
}*/
idxArr = new LinkedList<int>();
}
//Add
public void Add(int key, int value)
{
int hash = key % capacity;
while (eleArr[hash] != null && eleArr[hash].GetKey() != key)
{
hash = (hash + 1) % capacity;
}
eleArr[hash] = new HashEntry(key, value);
idxArr.AddFirst(hash);
}
//Search
public int Get(int key)
{
int hash = key % capacity;
while (eleArr[hash] != null && eleArr[hash].GetKey() != key)
{
hash = (hash + 1) % capacity;
}
//Not exist
if (eleArr[hash] == null)
return -1;
else
return eleArr[hash].GetValue();
}
//Clear, is it a true O(1) time?
public void Clear()
{
var newEleArr = new HashEntry[capacity];
var newIdxArr = new LinkedList<int>();
eleArr = newEleArr;
idxArr = newIdxArr;
}
//Delete
public void Delete(int key)
{
int hash = key % capacity;
eleArr[hash] = null;
//How to delete a element in the linked list in O(1) time??
}
//Iterator
public void Iterate()
{
var idxEnumerator = idxArr.GetEnumerator();
while (idxEnumerator.MoveNext() && idxEnumerator.Current != null)
{
int idx = idxEnumerator.Current;
if (eleArr[idx] != null)
{
Console.WriteLine("Key: " + eleArr[idx].GetKey() + "Value: " + eleArr[idx].GetValue());
}
}
}
}
Suggest an efficient way to find last position in heap satisfying the following conditions:
1) via pointers not via array
2) where we can insert or delete node
I could find it in O(n) time complexity but suggest a way which is of O(logn) or O(1) time complexity.
I'm assuming here that you mean a binary heap.
If you know how many nodes are in the heap, you can find the last node in O(log n) time by converting the count to binary, and then following the path of bits from high to low. That is, take the left node if the bit is 0, and the right node if the bit is 1.
For example, if there are three nodes in the heap, the binary representation of the count is 11. The root is always the first node, leaving you with 1. Then you take the right branch to get the last node.
Say there are 5 nodes in the heap:
1
2 3
4 5
In binary, that's 101. So you take the root. The next digit is 0 so you take the left branch. The next digit is 1, so you take the right branch, leaving you at node 5.
If you want the next available slot, you add 1 to the count and do the same thing. So 6 would be 110. You take the root, then the right branch, and the left child of 3 is where you'd add the new node.
You can do the same kind of thing with any d-ary heap, except that instead of converting to binary you convert to base d. So if your heap nodes each have up to three children, you'd convert the count to base 3, and use essentially the same logic as above.
An alternative is to maintain a reference to the last node in the heap, updating it every time you modify the heap. Or, if you want to know where the next node would be placed, you maintain a reference to the first node that doesn't have two children. That's O(1), but requires bookkeeping on every insertion or deletion.
I am answering my own question, There is no need to keep track of next pointer while inserting in heap (heap via pointers), even there is no need to keep track of parent, i am attaching running java code for heap, all possible method are included in it, getMin() = O(1), insert() = O(logn), extractMin = O(logn), decreasePriorityOfHead = O(logn), I have implemented it for generic code so it would be helpful to understand generic concept also.
class MinHeap<E extends Comparable<E>> {
private DoublyNode<E> root;
private int size = 0;
public DoublyNode<E> getRoot() {
return root;
}
public void setRoot(DoublyNode<E> root) {
this.root = root;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public MinHeap() {
}
public MinHeap(E data) {
this.root = new DoublyNode<E>(data);
this.size++;
}
private class NodeLevel<E extends Comparable<E>> {
private int level;
private DoublyNode<E> node;
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public DoublyNode<E> getNode() {
return node;
}
public void setNode(DoublyNode<E> node) {
this.node = node;
}
public NodeLevel(DoublyNode<E> node, int level) {
this.node = node;
this.level = level;
}
}
public void insert(E data) {
if (this.size == 0) {
this.root = new DoublyNode<E>(data);
this.size++;
return;
}
DoublyNode<E> tempRoot = this.root;
Integer insertingElementPosition = this.size + 1;
char[] insertingElementArray = Integer.toBinaryString(
insertingElementPosition).toCharArray();
DoublyNode<E> newNode = new DoublyNode<E>(data);
int i;
for (i = 1; i < insertingElementArray.length - 1; i++) {
if (newNode.getData().compareTo(tempRoot.getData()) < 0) {
this.swap(newNode, tempRoot);
}
char c = insertingElementArray[i];
if (c == '0') {
tempRoot = tempRoot.getLeft();
} else {
tempRoot = tempRoot.getRight();
}
}
// newNode.setParent(tempRoot);
if (newNode.getData().compareTo(tempRoot.getData()) < 0) {
this.swap(newNode, tempRoot);
}
if (insertingElementArray[i] == '0') {
tempRoot.setLeft(newNode);
} else {
tempRoot.setRight(newNode);
}
this.size++;
}
public void swap(DoublyNode<E> node1, DoublyNode<E> node2) {
E temp = node1.getData();
node1.setData(node2.getData());
node2.setData(temp);
}
public E getMin() {
if (this.size == 0) {
return null;
}
return this.root.getData();
}
public void heapifyDownWord(DoublyNode<E> temp) {
if (temp == null) {
return;
}
DoublyNode<E> smallerChild = this.getSmallerChild(temp);
if (smallerChild == null) {
return;
}
if (smallerChild.getData().compareTo(temp.getData()) < 0) {
this.swap(temp, smallerChild);
this.heapifyDownWord(smallerChild);
}
}
public DoublyNode<E> getSmallerChild(DoublyNode<E> temp) {
if (temp.getLeft() != null && temp.getRight() != null) {
return (temp.getLeft().getData()
.compareTo(temp.getRight().getData()) < 0) ? temp.getLeft()
: temp.getRight();
} else if (temp.getLeft() != null) {
return temp.getLeft();
} else {
return temp.getRight();
}
}
public E extractMin() {
if (this.root == null) {
return null;
}
E temp = this.root.getData();
if (this.root.getLeft() == null && this.root.getRight() == null) {
this.root = null;
this.size--;
return temp;
}
DoublyNode<E> parentOfLastData = this.getParentOfLastData();
if (parentOfLastData.getRight() != null) {
this.root.setData(parentOfLastData.getRight().getData());
parentOfLastData.setRight(null);
} else {
this.root.setData(parentOfLastData.getLeft().getData());
parentOfLastData.setLeft(null);
}
this.heapifyDownWord(this.root);
return temp;
}
public DoublyNode<E> getParentOfLastData() {
if (this.size == 0) {
return null;
}
DoublyNode<E> tempRoot = this.root;
Integer insertingElementPosition = this.size;
char[] insertingElementArray = Integer.toBinaryString(
insertingElementPosition).toCharArray();
int i;
for (i = 1; i < insertingElementArray.length - 1; i++) {
char c = insertingElementArray[i];
if (c == '0') {
tempRoot = tempRoot.getLeft();
} else {
tempRoot = tempRoot.getRight();
}
}
return tempRoot;
}
public DoublyNode<E> getParentOfLastEmptyPosition() {
if (this.size == 0) {
return null;
}
DoublyNode<E> tempRoot = this.root;
Integer insertingElementPosition = this.size + 1;
char[] insertingElementArray = Integer.toBinaryString(
insertingElementPosition).toCharArray();
System.out.println(insertingElementArray.toString());
int i;
for (i = 1; i < insertingElementArray.length - 1; i++) {
char c = insertingElementArray[i];
if (c == '0') {
tempRoot = tempRoot.getLeft();
} else {
tempRoot = tempRoot.getRight();
}
}
return tempRoot;
}
public void print() {
if (this.root == null) {
System.out.println("Heap via pointer is empty!");
return;
}
System.out.println("\n Heap via pointer is:- ");
Queue<NodeLevel<E>> dataQueue = new Queue<NodeLevel<E>>();
Queue<Space> spaceQueue = new Queue<Space>();
dataQueue.enQueue(new NodeLevel<E>(this.root, 1));
int heightOfTree = this.getHeightOfHeap();
Double powerHeghtBST = Math.pow(heightOfTree, 2);
spaceQueue.enQueue(new Space(powerHeghtBST.intValue(), false));
while (!dataQueue.isEmpty()) {
Space space = spaceQueue.deQueue();
NodeLevel<E> nodeLevel = dataQueue.deQueue();
while (space.isNullSpace()) {
space.printNullSpace();
spaceQueue.enQueue(space);
space = spaceQueue.deQueue();
}
space.printFrontSpace();
System.out.print(nodeLevel.getNode().getData().printingData());
space.printBackSpace();
if (nodeLevel.getNode().getLeft() != null) {
dataQueue.enQueue(new NodeLevel<E>(nodeLevel.getNode()
.getLeft(), nodeLevel.getLevel() + 1));
spaceQueue.enQueue(new Space(space.getSpaceSize() / 2, false));
} else {
spaceQueue.enQueue(new Space(space.getSpaceSize() / 2, true));
}
if (nodeLevel.getNode().getRight() != null) {
dataQueue.enQueue(new NodeLevel<E>(nodeLevel.getNode()
.getRight(), nodeLevel.getLevel() + 1));
spaceQueue.enQueue(new Space(space.getSpaceSize() / 2, false));
} else {
spaceQueue.enQueue(new Space(space.getSpaceSize() / 2, true));
}
if (!dataQueue.isEmpty()
&& nodeLevel.getLevel() + 1 == dataQueue.getFrontData()
.getLevel()) {
System.out.println("\n");
}
}
}
public int getHeightOfHeap() {
if (this.size == 0) {
return 0;
}
Double height = Math.log(this.size) / Math.log(2) + 1;
return height.intValue();
}
public void changePriorityOfHeapTop(E data) {
if (this.root == null) {
return;
}
this.root.setData(data);
this.heapifyDownWord(this.root);
}
}
interface Comparable<T> extends java.lang.Comparable<T> {
/**
* this methos returns a string of that data which to be shown during
* printing tree
*
* #return
*/
public String printingData();
}
public class PracticeMainClass {
public static void main(String[] args) {
MinHeap<Student> minHeap1 = new MinHeap<Student>();
minHeap1.insert(new Student(50, "a"));
minHeap1.insert(new Student(20, "a"));
minHeap1.insert(new Student(60, "a"));
minHeap1.insert(new Student(30, "a"));
minHeap1.insert(new Student(40, "a"));
minHeap1.insert(new Student(70, "a"));
minHeap1.insert(new Student(10, "a"));
minHeap1.insert(new Student(55, "a"));
minHeap1.insert(new Student(35, "a"));
minHeap1.insert(new Student(45, "a"));
minHeap1.print();
minHeap1.getMin();
minHeap1.print();
System.out
.println("\nminimum is:- " + minHeap1.getMin().printingData());
minHeap1.print();
System.out.println("\nminimum is:- "
+ minHeap1.extractMin().printingData());
minHeap1.print();
minHeap1.changePriorityOfHeapTop(new Student(75, "a"));
minHeap1.print();
}
}
class DoublyNode<E extends Comparable<E>> {
private E data;
private DoublyNode<E> left;
private DoublyNode<E> right;
// private DoublyNode<E> parent;
public DoublyNode() {
}
public DoublyNode(E data) {
this.data = data;
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
public DoublyNode<E> getLeft() {
return left;
}
public void setLeft(DoublyNode<E> left) {
this.left = left;
}
public DoublyNode<E> getRight() {
return right;
}
public void setRight(DoublyNode<E> right) {
this.right = right;
}
// public DoublyNode<E> getParent() {
// return parent;
// }
// public void setParent(DoublyNode<E> parent) {
// this.parent = parent;
// }
}
class Space {
private boolean isNullSpace = false;
private String frontSpace;
private String backSpace;
private String nullSpace;
private int spaceSize;
public boolean isNullSpace() {
return isNullSpace;
}
public void setNullSpace(boolean isNullSpace) {
this.isNullSpace = isNullSpace;
}
public int getSpaceSize() {
return spaceSize;
}
public void setSpaceSize(int spaceSize) {
this.spaceSize = spaceSize;
}
public Space(int spaceSize, boolean isNullSpace) {
this.isNullSpace = isNullSpace;
this.spaceSize = spaceSize;
if (spaceSize == 0) {
this.frontSpace = "";
this.backSpace = "";
this.nullSpace = " ";
} else if (spaceSize == 1) {
this.frontSpace = " ";
this.backSpace = "";
this.nullSpace = " ";
} else if (spaceSize == 2) {
this.frontSpace = " ";
this.backSpace = "";
this.nullSpace = " ";
} else {
this.frontSpace = String.format("%" + (spaceSize) + "s", " ");
this.backSpace = String.format("%" + (spaceSize - 2) + "s", " ");
this.nullSpace = String.format("%" + 2 * (spaceSize) + "s", " ");
}
}
public void printFrontSpace() {
System.out.print(this.frontSpace);
}
public void printBackSpace() {
System.out.print(this.backSpace);
}
public void printNullSpace() {
System.out.print(this.nullSpace);
}
}
class Queue<E> {
private Node<E> front;
private Node<E> rear;
private int queueSize = 0;
public Queue() {
}
public Queue(E data) {
this.front = new Node(data);
this.rear = this.front;
}
public void enQueue(E data) {
if (this.rear == null) {
this.rear = new Node(data);
this.front = this.rear;
} else {
Node newNode = new Node(data);
this.rear.setNext(newNode);
this.rear = newNode;
}
this.queueSize++;
}
public E deQueue() {
E returnValue;
if (this.front == null) {
return null;
} else if (this.front == this.rear) {
returnValue = this.front.getData();
this.front = null;
this.rear = null;
} else {
returnValue = this.front.getData();
this.front = this.front.getNext();
}
this.queueSize--;
return returnValue;
}
public void print() {
Node temp = this.front;
System.out.print("\n Queue is:- ");
if (temp == null) {
System.out.println(" Empty! ");
}
while (temp != null) {
System.out.print(temp.getData() + ",");
temp = temp.getNext();
}
}
public int getQueueSize() {
return queueSize;
}
public E getFrontData() {
if (this.front == null) {
System.out.println("queue is empty!");
return null;
}
return this.front.getData();
}
public E getRearData() {
if (this.rear == null) {
System.out.println("queue is empty!");
return null;
}
return this.rear.getData();
}
public boolean isEmpty() {
return this.front == null;
}
}
class Node<E> {
private E data;
private Node next;
public Node(E data) {
this.data = data;
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
class Student implements Comparable<Student> {
private int id;
private String name;
#Override
public int compareTo(Student student) {
if (this.id == student.id) {
return 0;
} else if (this.id < student.id) {
return -1;
} else {
return 1;
}
}
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String printingData() {
// String printingData = "{ id: "+this.id+" name: "+this.name+" }";
String printingData = String.valueOf(this.id);
return printingData;
}
}
Output of this code is:-
Heap via pointer is:-
10
30 20
35 40 70 60
55 50 45
Heap via pointer is:-
10
30 20
35 40 70 60
55 50 45
minimum is:- 10
Heap via pointer is:-
10
30 20
35 40 70 60
55 50 45
minimum is:- 10
Heap via pointer is:-
20
30 45
35 40 70 60
55 50
Heap via pointer is:-
30
35 45
50 40 70 60
55 75
Assume length of element in table is 1 or 2.
Table: { h, fe, na, o}
input string: nafeo
Output: true
Table: {ab,bc}
input string: abc
Output: false
Please advise my below code will cover all the cases and is this the best solution? Or am I missing anything, any alternate solutions?
import java.util.*;
public class CustomTable {
Set<String> table = new HashSet<String>();
public CustomTable(){
// add your elements here for more test cases
table.add("oh");
table.add("he");
}
public int checkTable( String prev, String curr, String next) {
System.out.print(prev+":"+curr+":"+next);
System.out.println();
if (prev!=null) if (table.contains(prev)) return -1;
if (table.contains(curr)) return 0;
if (table.contains(next)) return 1;
return 2;
}
// ohhe.
public static void main(String args[]) {
CustomTable obj = new CustomTable();
String inputStr = "ohheo"; //Tested ohe,ohhe,ohohe
int result = 0;
String curr, prev, next;
for (int i = 0; i < inputStr.length(); i++) {
// if prev element is found
if (result==-1){
prev = null;
}
else {
if (i > 0) {
prev = inputStr.substring(i - 1, i + 1);
} else {
prev = inputStr.substring(i, i + 1);
}
}
curr = inputStr.substring(i,i+1);
if (i < inputStr.length()-1) {
next = inputStr.substring(i, i+2);
} else {
next = inputStr.substring(i, i+1);
}
result = obj.checkTable(prev, curr, next);
if (result==2) {
System.out.print("false");
return;
}
}
System.out.print("true");
}
}
I think the problem have similarities to well known subset sum problem and you can use its solutions by some customization.