Shifting elements in an array? - java

I would like to make something where the strings will move up in an orderly fashion. For example:
Iteration 1:
Hello There
I am
Asking a question
To you
Iteration 2:
I am
Asking a question
To you
Next String
How exactly would I go about this, in the least memory-intensive way? Thanks.

An easy way is a circular queue.
A circular queue can be implemented as an array and a pointer to the first index. When you want to change the first element, you need only advance the index. When the index passes the end of the array, it rolls back to index 0.
With a circular queue:
Moving up the strings does not require moving anything in the array.
All the entries in the queue can be stored in an array, which requires less memory than a linked implementation.

If you're not obliged to use an array i would suggest a queue, with it its fairly simple to implement what you wanna do.
Queue<String> foo = new Queue<String>();
foo.offer("Hello"); //first element is hello
foo.offer("world"); //second element is world
String s = foo.poll(); //s = hello and now the first element of the queue is world

Related

Fastest way to reverse the order of a PriorityQueue in Java

In my implementation, I am adding objects to a PriorityQueue based on the value of a parameter a that they have. Simply said, I am adding elements to the PriorityQueue such that the elements with the largest value are in front of the queue by using the Comparator.comparingDouble(Object -> -Object.a). Whenever the size of the queue is larger than a predefined threshold, I poll an element for the queue. In this way, the queue will contain the elements with the most negative value.
In the next part of my code, I want to consider the elements in the queue in increasing order of the value of a, thus the reverse of the queue I am currently having.
What is the fastest way to do this/what other options for the first part do I have?
In the following, I worked out a small example to illustrate what I want to have. Suppose I have a list with five elements [4,2,7,9,1] and I want to keep the three smallest one.
The Priorityqueue will then equal:
[4]
[4,2]
[7,4,2]
[9,7,4,2] -> [7,4,2] after poll()
[7,4,2,1] -> [4,2,1] after poll()
For my next part of the code I would like to iterate over the reverse of this queue: [1,2,4].
Note that this example is rather easy and simple, but that in my code the list can easily contain more than 1,000,000 elements.
I am open for all suggestions!
PriorityQueue is implemented as a heap data structure; as such, its elements are not really ordered. Finding the largest element in a heap is O(1), but finding the smallest is O(n). You won't be able to easily obtain a reversed view from the data structure itself.
So, the answer to your question will be expensive computationally:
PriorityQueue<Integer> queue;
// this step will be expensive ~ n log(n)
List<Integer> values = queue.stream().sorted().collect(Collectors.toList());
// this also won't be cheap ~ n
Collections.reverse(values);
Depending on your usage patterns, you may want to opt for a data structure that might be more expensive to add to and remove from, but is cheaper to reverse. TreeSet comes to mind with its .iterator() and .descendingIterator() methods.

What is the time complexity of the add and element in a Java Array?

Hello I am research about that, but I cannot found anything in the oracle website.
The question is the next.
If you are using an static Array like this
int[] foo = new int[10];
And you want add some value to the 4 position of this ways
foor[4] = 4;
That don't shift the elements of the array so the time complexity will be O(1) because if you array start at 0x000001, and have 10 spaces, and you want put some in the x position you can access by (x*sizeOf(int))+initialMemoryPosition (this is a pseudocode)
Is this right, is this the way of that this type of array works in java, and if its time complexity O(1)
Thanks
The question is based on a misconception: in Java, you can't add elements to an array.
An array gets allocated once, initially, with a predefined number of entries. It is not possible to change that number later on.
In other words:
int a[] = new int[5];
a[4] = 5;
doesn't add anything. It just sets a value in memory.
So, if at all, we could say that we have somehow "O(1)" for accessing an address in memory, as nothing related to arrays depends on the number of entries.
Note: if you ask about ArrayList, things are different, as here adding to the end of the array can cause the creation of a new, larger (underlying) array, and moving of data.
An array is somewhere in memory. You don’t have control where, and you should not care where it is. The array is initialized when using the new type[size] syntax is used.
Accessing the array is done using the [] index operator. It will never modify size or order. Just the indexed location if you assign to it.
See also https://www.w3schools.com/java/java_arrays.asp
The time complexity is already correctly commented on. But that is the concern after getting the syntax right.
An old post regarding time complexity of collections can be found here.
Yes, it takes O(1) time. When you initialize an array, lets say, int[] foo = new int[10],
then it will create a new array with 0s. Since int has 4 bytes, which is 32 bits, every time assign a value to one element, i.e., foo[4] = 5, it will do foo[32 x input(which is 4)] = value(5); That's why array is 0-indexed, and how they assign values in O(1) time.

Insertion at the end of a linked list is not a special case. So what about the end of an array?

So, I was reading my textbook about linked lists. So if it isn't a special case if something is inserted at the end of a linked list, is it a special case, by way of contrast if an element is inserted at the end of an array? What is the reason behind the answer. Why? Why isn't it a special case when inserted at the end of a link list and why is/isn't a special case at the end of an array? What about for ArrayLists?
It is also not a special case for Array (if we are not talking about exceeding bounds of Array). But for ArrayList it could be a special case, because ArrayList has a capacity and if it is exceded ArrayList needs to be resized in order to make sure that it has space for inserted element.
Arrays have a fixed size that you give at initialization (This part is important because array elements are stored at consecutive memory addresses). Hence, you cannot append an element to an array without creating a new array.
int[] myArray = new int[10];
myArray.append(42); //Where should it be stored? It would not make sense.
For lists, it depends on the list implementation. The LinkedList consists of several Node connected to each other. Hence, adding an element to the end of the list is equivalent to connecting a new Node to the last Node of the list.

How can we reduce search time in linked list?

I read this question on career cup but didn't find any good answer other than 'SkipList'. The description of SkipList that I found on wikipedia was interesting, however, I didn't understand some terms like 'geometric/binomial distrubution'... I read what it is and goes deep into probabilistic theory. I simply wanted to implement a way to make some searching quicker. So here's what I did:
1. Created indexes.
- I wrote a function to create say 1000 nodes. Then, I created an array of type linked list and looped through the 1000 nodes and picked every 23rd element (random number that came in my mind) and added to the array which I call 'index'.
SLL index = new SLL[50]
Now the function to to create the index:
private static void createIndex(SLL[] index, SLL head){
int count=0;
SLL temp = head;
while(temp!=null)
{
count++;
temp = temp.next;
if((count==23){
index[i] = temp;
i++;
count=0;
}
}
}
Now finally the 'find' function. In that function, I first take the input element say 769 for example. I go through the 'index' array and find index[i]>769. Thus, now I pass head = index[i-1] and tail = index[i] to the 'find' function. It will then search between a short range of 23 elements for 769. Thus, I calculated that it takes a total of 43 jumps (including the array jumps and the node=node.next jumps) to find the element I wanted which otherwise would have taken 769 jumps.
Please Note: I consider the code to create index array NOT a part of searching, thus I do not add its time complexitiy(which is terrible) with the 'find' function's time complexity. I assume that this creation of index should be done as a separate function after a list has been created, OR, do it timely. Just like it takes time for a webpage to show up on google searches.
Also, this question was asked in a Microsoft interview and I wonder if the solution I provided would be any good or would I look like a fool for providing such kind of a solution. The solution has been written in Java.
Waiting for your feedback.
It is difficult to make out what problem it is that you are trying to solve here, or how your solution is supposed to work. (Hint: complete working code would help with both!)
However there are a couple of general things we can say:
You can't search a list data structure (e.g. find i in the list) in better that O(N) unless some kind of ordering has been placed on it. For example, sorting the elements.
If the elements of the list are sorted and your list is indexable (i.e. getting the element at position i is O(1)), then you can use binary search and find an element in O(logN).
You can't get the element at position i of a linked list in better that O(N).
If you add secondary data (indexes, whatever), you can potentially get better performance for certain operations ... at the expense of more storage space, and making certain other operations more expensive. However, you no longer have a list / linked list. The entire data structure is "something else".

Array operation, adding element at the end, pushing the other elements back

I'm planning to do a small program that'll display a graph which will be updated a few times per second (maybe 100/200ms or so). The purpose is to plot over 1000 different values in the graph, somewhat like an XY plot.
When the array contains 1000 elements, I'd like to add a new element at the end, and in the process pushing all the other elements one step back. In essence, element 999 would become 998, and 998 would become 997... all the way to the first element, which would simply be thrown away. Does anyone have an example or a good algorithm for doing this, either with regular arrays, Vector, LinkedList or any other method?
My first thought would be to create a new array and copy the elements that I want to keep into the new one, throwing away say the first 100 elements. At this point, I'd add the new 100 elements at the end of the array, and keep repeating this process, but surely there must be a better way of doing this?
What you are asking about is called deque in the algorithmic world, i.e. double ended vector.
That is the class you will need.
Basically deque supports adding and removing elements from both the beginning and the end of the sequence.
EDIT Actually as I read through the documentation I was surprised to see that the sdk implementation of deque does not support direct indexing (I am used to using this structure in C++). So I kept on searching and found this answer, linking to this library, which might be of help for you.
Don't use an Array, the complexity of moving all elements is awful! The Java data structure that's best suited for this task is a Deque, I'd say.
I would keep on reusing the same array, and just restart at the beginning. To make myself more clear, suppose you have your array with elements 1..1000
int[] array = new int[1000];
...
array = {1, 2, ...., 1000 };
If you now have to add element 1001, instead of trying to have an array {2, 3, ..., 1000, 1001}, I would go for an array {1001, 2, 3, ... 1000} and just keep track at which index my array actually starts. This replaces the difficulty of moving all elements by keeping a simple counter to the begin-index. To make it easy for yourself, you can introduce a utility method
private int startIndex = 1;//0 at the start
//I assume we are in the situation with array {1001, 2, 3, ..., 1000 }
public int convertIndex( int index ){
return (index + startIndex) % 1000;
}

Categories

Resources