Singly linked list counting algorithm - java

I need to write a metod that goes over a sorted singly linked list and returns
the number that appears the most times but goes over the list only one time.
Can someone point me in the right direction?
Can't find an elegent solution yet, should I use recursion?
I want the code to be as efficient as possible.
Thanks in advance.

You may use HashMap<index,count>
traverse linked list
if you find same number then incr count
at last check which count is great and return its index.

public int findMoreRecurrentValue(List<Integer> sortedList) {
if(sortedList.size() == 0) return -1;
int mostRecurrent = -1;
int nReccurrences = 0;
int n = 1;
int current = sortedList.get(0);
for(int i = 1; i < sortedList.size(); ++i) {
if(sortedList.get(i) == current)
++n;
else {
if(n > nReccurrences) {
mostRecurrent = current;
nReccurrences = n;
}
current = sortedList.get(i);
n = 1;
}
}
// Check again at the end, the most reccurrent value could be the last one.
if(n > nReccurrences) {
mostRecurrent = current;
nReccurrences = n;
}
return mostRecurrent;
}

Related

Solution timing out for question: build binary tree from inorder and postorder

I've been grinding leetcode recently and am perplexed on why my solution is timing out when I submit it to Leetcode.
Here is the question:
https://leetcode.com/explore/learn/card/data-structure-tree/133/conclusion/942/
Given inorder and postorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
For example, given
inorder = [9,3,15,20,7]
postorder = [9,15,7,20,3]
Return the following binary tree:
3
/ \
9 20
/ \
15 7
Here is my solution that times out in one of the test cases:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
if (inorder == null || inorder.length == 0) {
return null; // input error
}
if (postorder == null || postorder.length == 0) {
return null; // input error
}
if (postorder.length != inorder.length) {
return null; // input error
}
List<Integer> inOrder = new ArrayList<Integer>();
List<Integer> postOrder = new ArrayList<Integer>();
for (int i = 0; i < inorder.length; i++) {
inOrder.add(inorder[i]);
postOrder.add(postorder[i]);
}
return buildBinaryTree(inOrder, postOrder);
}
public TreeNode buildBinaryTree(List<Integer> inOrder, List<Integer> postOrder) {
boolean found = false;
int root = 0;
int rootIndex = 0;
// for given in-order scan the post-order right to left to find the root
for (int j = postOrder.size() - 1; j >= 0 && !found; j--) {
root = postOrder.get(j);
if (inOrder.contains(root)) {
rootIndex = inOrder.indexOf(root);
root = inOrder.get(rootIndex);
found = true;
break;
}
}
if (found) {
List<Integer> leftOfRoot = new ArrayList<Integer>();
List<Integer> rightOfRoot = new ArrayList<Integer>();
if (rootIndex > 0) {
leftOfRoot.addAll(inOrder.subList(0, rootIndex));
}
if ((rootIndex + 1) < inOrder.size()) {
rightOfRoot.addAll(inOrder.subList(rootIndex + 1, inOrder.size()));
}
TreeNode node = new TreeNode(root);
node.left = buildBinaryTree(leftOfRoot, postOrder);
node.right = buildBinaryTree(rightOfRoot, postOrder);
return node;
}
return null;
}
}
Can anyone help determine why this is happening? I'm thinking it is the Leetcode judge at fault here and my code is fine.
Leetcode's judge is probably OK. This code is too casual about nested linear array operations and heap allocations. Creating ArrayLists and calling contains, addAll, subList and indexOf may appear innocuous, but they should all be thought of as extremely expensive operations when inside a recursive function that spawns two child calls in every frame.
Let's unpack the code a bit:
List<Integer> inOrder = new ArrayList<Integer>();
List<Integer> postOrder = new ArrayList<Integer>();
for (int i = 0; i < inorder.length; i++) {
inOrder.add(inorder[i]);
postOrder.add(postorder[i]);
}
This is a minor up-front cost but it's an omen of things to come. We've done 2 heap allocations that weren't necessary and walked n. I'd stick to primitive arrays here--no need to allocate objects other than the result nodes. A lookup map for inOrder with value -> index pairs might be useful to allocate if you feel compelled to create a supporting data structure here.
Next, we step into buildBinaryTree. Its structure is basically:
function buildBinaryTree(root) {
// do some stuff
if (not base case reached) {
buildBinaryTree(root.left)
buildBinaryTree(root.right)
}
}
This is linear on the number of nodes in the tree, so it's important that // do some stuff is efficient, hopefully constant time. Walking n in this function would give us quadratic complexity.
Next there's
for (int j = postOrder.size() - 1; j >= 0 && !found; j--) {
root = postOrder.get(j);
if (inOrder.contains(root)) {
rootIndex = inOrder.indexOf(root);
This looks bad, but by definition the root is always the last element in a postorder traversal array, so if we keep a pointer to it, we can remove this outer loop. You can use indexOf directly and avoid the contains call since indexOf returns -1 to indicate a failed search.
The code:
if (found) {
List<Integer> leftOfRoot = new ArrayList<Integer>();
List<Integer> rightOfRoot = new ArrayList<Integer>();
does more unnecessary heap allocations for every call frame.
Here,
leftOfRoot.addAll(inOrder.subList(0, rootIndex));
Walks the list twice, once to create the sublist and again to add the entire sublist to the ArrayList. Repeat for the right subtree for two full walks on n per frame. Using start and end indices per call frame means you never need to allocate heap memory or copy anything to prepare the next call. Adjust the indices and pass a reference to the same two arrays along the entire time.
I recommend running your code with a profiler to see exactly how much time is spent copying and scanning your ArrayLists. The correct implementation should do at most one walk through one of the lists per call frame to locate root in inOrder. No array copying should be done at all.
With these modifications, you should be able to pass, although wrangling the pointers for this problem is not obvious. A hint that may help is this: recursively process the right subtree before the left.
Yes, it would be much faster with arrays. Try this:
public static TreeNode buildTree(int[] inorder, int[] postorder, int start,
int end) {
for (int i = postorder.length-1; i >= 0; --i) {
int root = postorder[i];
int index = indexOf(inorder, start, end, root);
if (index >= 0) {
TreeNode left = index == start
? null
: buildTree(inorder, postorder, start, index);
TreeNode right = index+1 == end
? null
: buildTree(inorder, postorder, index+1, end);
return new TreeNode(root, left, right);
}
}
return null;
}
private static int indexOf(int[] array, int start, int end, int value) {
for (int i = start; i < end; ++i) {
if (array[i] == value) {
return i;
}
}
return -1;
}

15 puzzle with AStar Algorithm

I've made a simple 15puzzle game using A-star algorithm with Manhattan Distance.
For easy problems it works, but the solution isn't the optimal one.
For example, if a movement is:
Right->Up
my solution would be:
Right->Up->Left->Down->Right->Up
If i have a hard game to solve, it takes infinite time and get no solution to problem, I think because of this problem.
To implement my game I have followed wikipedia pseudocode of A* algorithm.
Here is my AStar function:
public ArrayList<String> solution(Vector<Integer> start){
ArrayList<String> movePath = new ArrayList<String>(); //Path to solution
PriorityQueue<Node> closedQueue = new PriorityQueue<Node>(500,new Comparator<Node>() {
#Override public int compare(Node a,Node b) {
return a.get_fScore() - b.get_fScore();
}
});
Node node = new Node(start,movePath,heuristic);
int cnt =0;
openQueue.add(node);
while(!openQueue.isEmpty() ) {
//Alt if it takes too much time (ToRemove)
if(cnt == (150)*1000) {
ArrayList<String> noResult = new ArrayList<String>();
noResult.add("Timeout");
return noResult;
}
Node bestNode = openQueue.remove(); //Remove best node from openQueue
closedQueue.add(bestNode); //Insert its to closedQueue
cnt++;
if( cnt % 10000 == 0) {
System.out.printf("Analizzo %,d posizioni. Queue Size = %,d\n", cnt, openQueue.size());
}
//Get first step from bestNode and add to movePath
if(!bestNode.isEmptyMoves()) {
String step = bestNode.get_moves().get(0);
movePath.add(step);
}
//Exit Condition
if(bestNode.get_hScore() == 0) {
return bestNode.get_moves();
}
//Looking for childs
Vector<Node> childs = get_nextMoves(bestNode);
for(int i=0; i<childs.size(); i++) {
if(closedQueue.contains(childs.elementAt(i)))
continue;
childs.elementAt(i).set_gScore(bestNode.get_gScore()+1); //Increment level in tree
if(!openQueue.contains(childs.elementAt(i)))
openQueue.add(childs.elementAt(i));
else {
//!Never reached this level!
System.out.println("Here!");
//TODO Copy child from openQueue to closedQueue
}
}
}
return null;
That is my function to find neighbours:
public Vector<Node> get_nextMoves(Node act){
Vector<Node> steps = new Vector<Node>();
int position = act.get_valuePos(0);
String lastMove = act.get_lastMove();
//System.out.println(lastMove);
//Right Child
if(position + 1 < 16 && position + 1!=3 && position + 1!=7 && position+1 !=11 && lastMove !="Left") {
int temp_pos[] = copyToArray(act.get_posVect());//Copy array of positions of ACT to a temp_pos array
temp_pos[position] = temp_pos[position+1]; //Switch 0 position with Right position
temp_pos[position+1] = 0;
ArrayList<String> temp_moves = new ArrayList<String>();
for(int i=0; i<act.get_moves().size(); i++) {
temp_moves.add(act.get_moves().get(i)); //Save old steps
}
temp_moves.add("Right");//And add new one
Node child = new Node(temp_pos,temp_moves,act.get_heuristic()); //New Node
steps.addElement(child);//Added to vector
}
//Left Child
if(position - 1 >= 0 && position - 1 != 4 && position - 1 != 8 && position - 1 != 12 && lastMove !="Right") {
int temp_pos[] = copyToArray(act.get_posVect());
temp_pos[position] = temp_pos[position-1];
temp_pos[position-1] = 0;
ArrayList<String> temp_moves = new ArrayList<String>();
for(int i=0; i<act.get_moves().size(); i++) {
temp_moves.add(act.get_moves().get(i));
}
temp_moves.add("Left");
Node child = new Node(temp_pos,temp_moves,act.get_heuristic());
steps.addElement(child);
}
//Up Child
if(position - 4 >= 0 && lastMove !="Down") {
int temp_pos[] = copyToArray(act.get_posVect());
temp_pos[position] = temp_pos[position-4];
temp_pos[position-4] = 0;
ArrayList<String> temp_moves = new ArrayList<String>();
for(int i=0; i<act.get_moves().size(); i++) {
temp_moves.add(act.get_moves().get(i));
}
temp_moves.add("Up");
Node child = new Node(temp_pos,temp_moves,act.get_heuristic());
steps.addElement(child);
}
//Down Child
if(position + 4 < 16 && lastMove !="Up") {
int temp_pos[] = copyToArray(act.get_posVect());
temp_pos[position] = temp_pos[position+4];
temp_pos[position+4] = 0;
ArrayList<String> temp_moves = new ArrayList<String>();
for(int i=0; i<act.get_moves().size(); i++) {
temp_moves.add(act.get_moves().get(i));
}
temp_moves.add("Down");
Node child = new Node(temp_pos,temp_moves,act.get_heuristic());
steps.addElement(child);
}
return steps;
And that is my ManhattanDistance function:
public int calcolaDist(Vector<Integer> A) {
int result = 0;
Vector<Integer> goal_Mat = initialize_Mat();
for(int i=0; i<16; i++) {
int x_goal = (goal_Mat.indexOf(i))/4;
int y_goal = (goal_Mat.indexOf(i))%4;
int x_def = (A.indexOf(i))/4;
int y_def = (A.indexOf(i))%4;
if(A.elementAt(i) > 0) {
result += Math.abs(x_def - x_goal);
result += Math.abs(y_def - y_goal);
}
}
return result;
If my puzzle is:
start = {1,3,0,4,5,2,7,8,9,6,10,11,13,14,15,12}
My solution will be:
[Left, Down, Down, Right, Down, Right, Up, Left, Down, Right, Up, Left, Down, Right]
I know that using Vectors isn't a good choice and my code is "a little" dirty, but I'm going to clean its as soon as I get out of that problem!
Thank you all!
First, I see a bit of confusion in your code with the OPEN and CLOSED queues. The OPEN queue should be the one that manages the priority of the nodes (PriorityQueue). This is not needed for CLOSED, which only stores the visited nodes and their cost (maybe your algorithm will be more efficient changing CLOSED by a HashSet or HashMap to avoid ordering the nodes in CLOSED as well). I can't see in your code how you initialized the OPEN queue, but maybe that is one issue with your implementation of A*.
The other issue I see with your code is that with A*-based algorithms, you need to manage the situation in which you reach a node that is already in OPEN/CLOSED, but with a different cost. This can happen if you visit a node from different parents, or you enter in a loop. The algorithm will not work properly if you are not taking that into account.
If you visit a node that is already in the OPEN queue, and the new node has a lower f-score, you should remove the old node from OPEN and insert the one with the lower cost.
If the node has a higher cost (in OPEN or CLOSED) then you should simply discard that node to avoid loops.
The problem is though, but the state space is finite and the algorithm should finish at some point. I see that your implementation is in Java. Maybe it would be helpful for you if you take a look to the library Hipster4j, which has an implementation of A*, and an example solving the 8-puzzle.
I hope my answer helps. Good luck!

For k collections all of which have length = N, finding common elements with a O((k-1)*N)

I am supposed to write a code which is supposed to find the common elements existing in k collections of N-elements efficiently. All collections are sorted and they may have various sizes, but let's assume same sizes for the sake of simplicity here. Only thing that counts is the comparisons between elements; that should be less than O((k-1)*N).
I have developed the below code, but in case of mentioned scenario the number of comparisons is about (k-1)NN
Appreciate the help in advance.
//Arrays are sorted and the shortest array is chosen as the query automatically
boolean com;
loop1: for (int i = 0; i < QuetyList.length; ++i) {
com = false;
loop2: for (int k = 0; k < OtherLists.length; ++k) {
com = false;
loop3: for (int y = 0; y < OtherLists[k].size(); ++y) {
++comparisons;
if (QueryList[i].compareTo(OtherLists[k][y]) == 0) {
com = true;
break loop3;
}
++comparisons;
if (QueryList[i].compareTo(OtherLists[k][y]) < 0) {
break;
}
}
if (com == false) {
break;
}
}
if (com == true) {
commons.add(QueryList[i]);
}
}
Sample test
Comparable [] QuetyList = {200,200,200,200};
Comparable [] collection2 = {2,10,50,200};
Comparable [] collection3 = {2,10,40,200};
Comparable [][] OtherLists = {collection2,collection3};
This is for a homework. There is a chance you may have crossed sometime in your education. Thanks in advance.
The basic idea is to keep an index on every list you have, and only advance this index when the value at the index is the smallest among all the lists.
I can't see if it's doable for k lists at once, but it's certainly doable 2 lists at a time, each should take N comparisons, which should give you O(k * N) (k-1 runs of N comparison).
Something like:
public Comparable[] common(Comparable[] a, Comparable[] b) {
// List is more flexible, but the toArray at the end is a bit costly. You can probably figure a better way of doing this.
List<Comparable> res = new ArrayList<>();
int indexA = 0;
int indexB = 0;
while (indexA < a.length && indexB < b.length) {
// Exercice for the reader: replace with compareTo calls
if (a[indexA] == b[indexB]) {
// Common item!
res.add(a[indexA]);
indexA++;
indexB++;
} else if (a[indexA] < b[indexB]) {
// item in A is smaller, try the next
indexA++;
} else {
indexB++;
}
}
return res.toArray(new Comparable[0]);
}
From this, you can group your lists 2 by 2 until only one list remains.

Resolving method calls from generic object in enhanced for loop

This is more than likely a simple question for someone who is more familiar with Java than I am. Here's the gist of my issue:
I have a function that basically generates the possible combinations of the objects contained within an ArrayList. Being that I have multiple objects that need to use this function, the function is screaming at me to be made generic. The issue I'm encountering, though, is that an enhanced for-loop is unable to resolve method calls from the generic iterator. I understand why this happening, but I'm not familiar enough with Java to know how to resolve this issue. In any case, here is my code:
private <T> ArrayList<T> determineIdealOrderCombination(ArrayList<T> orders, int position){
// Local Variable Declarations
List<ArrayList<T>> subsets = new ArrayList<>();
int k = orders.size()+1; // Add one due to the do-while loop
int theoreticalQuantity;
int indexOfMaxProfit;
double maxProfit;
int[] s; // Here we'll keep indices pointing to elements in input array
double[] profits; // Here we'll keep track of the profit of each combination
// Begin searching for valid combinations
do {
// Setup
k--;
s = new int[k];
profits = new double[k];
// Generate combinations
if ( (k <= orders.size()) && (k > 0) ) {
// Set the first index sequence: 0, 1, 2,...
for (int i = 0; (s[i] = i) < k - 1; i++) ;
subsets.add(getSubset(orders, s));
for (; ; ) {
int i;
// Find position of item that can be incremented
for (i = k - 1; i >= 0 && s[i] == orders.size() - k + i; i--) ;
if (i < 0) {
break;
} else {
s[i]++; // increment this item
for (++i; i < k; i++) { // fill up remaining items
s[i] = s[i - 1] + 1;
}
subsets.add(getSubset(orders, s));
}
}
// All combinations have been evaluated, now throw away invalid combinations that violate the upper limit
// and calculate the valid combinations profits.
for (int i = 0; i < subsets.size(); i++) {
// Calculate the final position
theoreticalQuantity = position;
profits[i] = 0;
for (T t : subsets.get(i)) {
theoreticalQuantity += t.getQuantity(); // <-- THE PROBLEM
profits[i] += calculateProjectedProfit(t.getSecurity(), t.getQuantity(), t.getPrice()); // <-- THE PROBLEM
}
if(theoreticalQuantity > _MAX_POSITION_PER_ASSET){
// Negate profits if final position violates the position limit on an asset
profits[i] = Double.MIN_VALUE;
}
}
}
else{
break;
}
}
while( (subsets.size() == 0) );
// Verify that the subset array is not zero - it should never be zero
if(subsets.size() == 0){
return new ArrayList<>();
}
// Return the most profitable combination, if any.
indexOfMaxProfit = -1;
maxProfit = Double.MIN_VALUE;
for(int i = 0; i < profits.length; i++){
if(profits[i] != Double.MIN_VALUE){
if(profits[i] > maxProfit){
maxProfit = profits[i];
indexOfMaxProfit = i;
}
}
}
if( (maxProfit > 0) && (indexOfMaxProfit != -1) ){
return subsets.get(indexOfMaxProfit);
}
else{
return new ArrayList<>();
}
}
Any help would be appreciated.
This is how you tell the compiler that the incoming objects have the relevant methods:
public interface MyCommonInterface {
public int getQuantity();
}
private <T extends MyCommonInterface> ArrayList<T> determineIdealOrderCombination(ArrayList<T> orders, int position) {
As an additional note, i would read some tutorials on generics before attempting to use them. they are a little tricky to get the hang of initially. however, once you put out a little effort to learn the basics, you should be in a much better place to actually utilize them.

Why doesn't this return the position for the largest item in the array list

public static int findLargestMark(ArrayList<Result> array)
{
int last = 0;
int largestPOS = 0;
for (int i = 1; i <= array.size(); i++)
{
for (Result s : array)
{
int num = s.getMark();
if (num > last)
{
last = num;
largestPOS = i++;
}
}
}
Does anyone have any idea why this isn't returning the position of the largest value?
I'm sorry but I'm a bit of a newbie to Java.
largestPOS = i++;
This is incrementing i which means it skips the next number. If that next number is the biggest, you'll miss it.
Your code won't compile. You need a return statement.
Your outer loop skips the first element because it starts at 1 instead of 0. Arrays and lists are 0 based.
You only need one loop to accomplish this. I'd remove the inner loop since you're trying to return the index and a foreach loop doesn't give you the index.
If your array is empty, it will set largestPOS to 0. That is not correct. Other algorithms in this situation would return -1 to mean "index not found". See String.indexOf for example.
If you want to find the largest mark, no need to reinvent the wheel. Use Collections.max and provide a custom Comparator :
Result r = Collections.max(array, new Comparator<Result>() {
#Override
public int compare(Result o1, Result o2) {
return Integer.compare(o1.getMark(), o2.getMark());
}
});
Then if you really want to find the position of this object in the list you can use indexOf :
array.indexOf(r);
Note that will return the index of the first occurrence of the specified element in the list.
If you want to get the index of the last occurrence, you can use :
array.lastIndexOf(r);
There are several reasons to this program's failure:
You need to check that your array has at least one item
You need to start the last at the initial mark, not at zero
You need to loop from one, inclusive, to array.size(), exclusive
You do not need a nested loop
You need to add a return statement
Here is how you can fix your code:
public static int findLargestMark(ArrayList<Result> array) {
if (array.size() == 0) return -1; //
int last = array.get(0).getMark();
int largestPOS = 0;
for (int i = 1; i < array.size(); i++) {
int num = array.get(i).getMark();
if (num > last) {
last = num;
largestPOS = i;
}
}
return largestPOS;
}
Because you're iterating through the same array using two nested loops. Keep it simple. Iterate only once through the entire array and find the maximum value and its index.
Try this..
public static int findLargestMark(ArrayList<Result> array)
{
int last = array.get(0).getMark();
int largestPOS = 0;
for (int i = 1; i <= array.size(); i++)
{
Result s = array.get(i);
int num = s.getMark();
if (num > last)
{
last = num;
largestPOS = i;
}
}
return largestPOS;
}
Your code even not compile, java is 0 index based. you should have received a ArrayIndexOfBoundException. However, i would just use Collections.max(array, Comparator):
Result x = Collections.max(array, new Comparator<Result>(){
#Override
public int compare(Result o1, Result o2) {
return Integer.compare(o1.getMark(), o2.getMark());
}
});
And then the index by array.indexOf(x) function, where array is an instance of type ArrayList<Result>

Categories