I am doing some practice where I have to find all the permutations of n numbers. I was given pseudo code, however, I am having difficulties translating it.
public void nextPerm(int[] a,int pivot,int suc){
suc = 0;
pivot = 0;
for(int i = a.length-1;; i--){
if( i+1 != a.length)
if(a[i] < a[i+1]){
pivot = i;
break;
} else if(pivot == 0){
reverseArray(a,pivot);//this just reverses the array from the right of the pivot point
System.out.println(a);
}
}
for(int i = a.length-1;;i--){
if(a[i] > a[pivot]){
suc = i;
break;
}
}
//swap pivot and suc
int place = a[pivot];
a[pivot] = a[suc];
a[place] = a[pivot];
reverseArray(a,pivot);
System.out.println(Arrays.toString(a));
}
private void reverseArray(int[] a,int pivot) {//make pivot the index which it will reverse to the right of
// TODO Auto-generated method stub
int[] place = new int[a.length-pivot-1];
int counter = 0;
for(int i = a.length-1; i > pivot;i--){
place[counter] = a[i];
counter++;
}
counter = 0;
int[] hold = new int[a.length];
for(int i = 0; i <= pivot;i++){
hold[i] = a[i];
counter++;
}
for(int i = 0; i < place.length;i++){
hold[counter] = place[i];
counter++;
}
System.out.println(Arrays.toString(hold));
}
This is what I have so far. Basically each time I run nextPerm it adjusts an array to be another permutation. For more info check out the pages here: link to more info
Summary: nextPerm finds all the possible perms one at a time by manually changing the array.
You just need to pass the output obtained in previous step as input to next step until you iterate over all possible permutations. Here is an explanation and pseudo code for the same.
Lets say that you have an array [1,2,3,4]. Total permutations possible with 4 elements in array would be 4! assuming all elements are distinct. So, just iterate the above code for nextPerm 4! times.
int fact = factorial(array.length);
for(int i = 0;i<fact;i++){
int[] b = nextPerm(array);
array = b;
}
assuming that your nextPrem returns you the next permutated array.
Related
I have wrote a method for the question:
input: an array of integers
return: the length of longest consecutive integer sequence.
like: for {9,1,2,3}, return 3, cuz{1,2,3}
the method doesnt run well. hope someone could help me with debugging.
public int solution(int[] arr){
int counter = 1;
int max = arr[1];
//find the max in the array
for (int i : arr){
if (i > max){
max = i;
}
}
int[] nArr = new int[max];
for (int i : arr){
nArr[i] = i;
}
List<Integer> counters = new ArrayList<>();
for (int i = 0; i < max; i++){
if (nArr[i] == nArr[i+1] - 1){
counter++;
}else{
counters.add(counter);
counter = 1;
}
}
max = counters.get(1);
for (int i : counters){
if (i > max){
max = i;
}
}
return max; }
thanks a lot!!!
You dont need to use ArrayList... If all you want is max count of sequential integers, then try this:
int[] a = somethingBlaBla;
int counter = 0; // Stores temporary maxes
int secCounter = 0; //Stores final max
for(int j = 0; j<a.length-1; j++){ // Iterate through array
if(a[j] == a[j+1]-1){
counter++; // If match found then increment counter
if(counter > secCounter)
secCounter = counter; // If current match is greater than stored match, replace current match
}
else
counter = 0; // Reset match to accumulate new match
}
System.out.println(secCounter);
As for your method, the first thing I noticed is that max has value of greatest number in array and not the size of array. So if my array is something like {1,2,3,45,6,7,8,9}, it will throw indexOutOfBoundsException because its gonna try get 45th element in array which is not present.
This question already has answers here:
How do I reverse an int array in Java?
(47 answers)
Closed 8 years ago.
I have an array of n elements and these methods:
last() return the last int of the array
first() return the first int of the array
size() return the length of the array
replaceFirst(num) that add the int at the beginning and returns its position
remove(pos) that delete the int at the pos
I have to create a new method that gives me the array at the reverse order.
I need to use those method. Now, I can't understand why my method doesn't work.
so
for (int i = 1; i
The remove will remove the element at the position i, and return the number that it is in that position, and then with replaceFirst will move the number (returned by remove) of the array.
I made a try with a simple array with {2,4,6,8,10,12}
My output is: 12 12 12 8 6 10
so if I have an array with 1,2,3,4,5
for i = 1; I'm gonna have : 2,1,3,4,5
for i=2 >3,2,1,4,5
etc
But it doesn't seem to work.
Well, I'll give you hints. There are multiple ways to reverse an array.
The simplest and the most obvious way would be to loop through the array in the reverse order and assign the values to another array in the right order.
The previous method would require you to use an extra array, and if you do not want to do that, you could have two indices in a for loop, one from the first and next from the last and start swapping the values at those indices.
Your method also works, but since you insert the values into the front of the array, its going to be a bit more complex.
There is also a Collections.reverse method in the Collections class to reverse arrays of objects. You can read about it in this post
Here is an code that was put up on Stackoverflow by #unholysampler. You might want to start there: Java array order reversing
public static void reverse(int[] a)
{
int l = a.length;
for (int j = 0; j < l / 2; j++)
{
int temp = a[j]
a[j] = a[l - j - 1];
a[l - j - 1] = temp;
}
}
int[] reverse(int[] a) {
int len = a.length;
int[] result = new int[len];
for (int i = len; i > 0 ; i--)
result[len-i] = a[i-1];
return result;
}
for(int i = array.length; i >= 0; i--){
System.out.printf("%d\n",array[i]);
}
Try this.
If it is a Java array and not a complex type, the easiest and safest way is to use a library, e.g. Apache commons: ArrayUtils.reverse(array);
In Java for a random Array:
public static void reverse(){
int[] a = new int[4];
a[0] = 3;
a[1] = 2;
a[2] = 5;
a[3] = 1;
LinkedList<Integer> b = new LinkedList<Integer>();
for(int i = a.length-1; i >= 0; i--){
b.add(a[i]);
}
for(int i=0; i<b.size(); i++){
a[i] = b.get(i);
System.out.print(a[i] + ",");
}
}
Hope this helps.
Reversing an array is a relatively simple process. Let's start with thinking how you print an array normally.
int[] numbers = {1,2,3,4,5,6};
for(int x = 0; x < numbers.length; x++)
{
System.out.println(numbers[x]);
}
What does this do? Well it increments x while it is less than numbers.length, so what is actually happening is..
First run : X = 0
System.out.println(numbers[x]);
// Which is equivalent to..
System.out.println(numbers[0]);
// Which resolves to..
System.out.println(1);
Second Run : X = 1
System.out.println(numbers[x]);
// Which is equivalent to..
System.out.println(numbers[1]);
// Which resolves to..
System.out.println(2);
What you need to do is start with numbers.length - 1, and go back down to 0. To do this, you need to restructure your for loop, to match the following pseudocode..
for(x := numbers.length to 0) {
print numbers[x]
}
Now you've worked out how to print, it's time to move onto reversing the array. Using your for loop, you can cycle through each value in the array from start to finish. You'll also be needing a new array.
int[] revNumbers = new int[numbers.length];
for(int x = numbers.length - 1 to 0) {
revNumbers[(numbers.length - 1) - x] = numbers[x];
}
int[] noArray = {1,2,3,4,5,6};
int lenght = noArray.length - 1;
for(int x = lenght ; x >= 0; x--)
{
System.out.println(noArray[x]);
}
}
int[] numbers = {1,2,3,4,5};
int[] ReverseNumbers = new int[numbers.Length];
for(int a=0; a<numbers.Length; a++)
{
ReverseNumbers[a] = numbers.Length - a;
}
for(int a=0; a<ReverseNumbers.Length; a++)
Console.Write(" " + ReverseNumbers[a]);
int[] numbers = { 1, 2, 3, 4, 5, 6 };
reverse(numbers, 1); >2,1,3,4,5
reverse(numbers, 2); >3,2,1,4,5
public int[] reverse(int[] numbers, int value) {
int index = 0;
for (int i = 0; i < numbers.length; i++) {
int j = numbers[i];
if (j == value) {
index = i;
break;
}
}
int i = 0;
int[] result = new int[numbers.length];
int forIndex = index + 1;
for (int x = index + 2; x > 0; x--) {
result[i] = numbers[forIndex--];
++i;
}
for (int x = index + 2; x < numbers.length; x++) {
result[i] = numbers[x];
++i;
}
return result;
}
Im trying to generate an array with 1000 integers of non-repeating numbers in ascending order from 0 to 10,000
So far what I have is:
public static void InitArray(int[] arr) { // InitArray method
int i, a_num; // int declared
Random my_rand_obj = new Random(); // random numbers
for (i = 0; i <= arr.length-1; i++) // for loop
{
a_num = my_rand_obj.nextInt(10000); // acquiring random numbers from 0 - 10000
arr[i] = a_num; // numbers being put into array (previoulsy declared of size 1000)
}
}
public static void ShowArray(int[] arr) { // ShowArray method
int i; // int declared
for (i = 0; i <= arr.length-1; i++) { // for loop
System.out.print(arr[i] + " "); // show current array content
}
System.out.println(); // empty line
}
public static void Sort(int[] arr) { // SortArray method
int i, min, j; // int decalred
for (i = 0; i < arr.length-1; i++) { // for loop
min = i; // min is i
for (j = i + 1; j < arr.length; j++) { // nested for loop
if (arr[j] < arr[min]) { // if statement
min = j; // j is the new minimum
}
}
int swap = arr[min]; // swap "method"
arr[min] = arr[i];
arr[i] = swap;
}
}
Is there any way to check the numbers are not repeating? Is there a function besides the random generator that will let me generate numbers without repeating? Thanks for any help
You can declare array of size 10,000
and init the array in away that each cell in the array will holds the value of it's index:
int [] arr= new int[10000];
for (int i=0 i < arr.length; i++){
arr[i] = i
}
Now you can shuffle the array using java Collections.
and take the first 1000 items from the array and sort then using java sort.
This will do I believe..
HashSet hs = new HashSet();
for(int i=0;i< arr.length;i++)
hs.add(arr[i]);
List<Integer> integers=new ArrayList<>(hs);
Collections.sort(integers);
A very simple solution is to generate the numbers cleverly. I have a solution. Though it may not have an even distribution, it's as simple as it can get. So, here goes:
public static int[] randomSortedArray (int minLimit, int maxLimit, int size) {
int range = (maxLimit - minLimit) / size;
int[] array = new int[size];
Random rand = new Random();
for (int i = 0; i < array.length; i++ ) {
array[i] = minLimit + rand.nextInt(range) + range * i;
}
return array;
}
So, in your case, call the method as:
int randomSortedArray = randomSortedArray(0, 10_000, 1_000);
It's very simple and doesn't require any sorting algorithm. It simply runs a single loop which makes it run in linear time (i.e. it is of time complexity = O(1)).
As a result, you get a randomly generated, "pre-sorted" int[] (int array) in unbelievable time!
Post a comment if you need an explanation of the algorithm (though it's fairly simple).
I have to write a method that takes an array of ints that is already sorted in numerical order then remove all the duplicate numbers and return an array of just the numbers that have no duplicates. That array must then be printed out so I can't have any null pointer exceptions. The method has to be in O(n) time, can't use vectors or hashes. This is what I have so far but it only has the first couple numbers in order without duplicates and then just puts the duplicates in the back of the array. I can't create a temporary array because it gives me null pointer exceptions.
public static int[] noDups(int[] myArray) {
int j = 0;
for (int i = 1; i < myArray.length; i++) {
if (myArray[i] != myArray[j]) {
j++;
myArray[j] = myArray[i];
}
}
return myArray;
}
Since this seems to be homework I don't want to give you the exact code, but here's what to do:
Do a first run through of the array to see how many duplicates there are
Create a new array of size (oldSize - duplicates)
Do another run through of the array to put the unique values in the new array
Since the array is sorted, you can just check if array[n] == array[n+1]. If not, then it isn't a duplicate. Be careful about your array bounds when checking n+1.
edit: because this involves two run throughs it will run in O(2n) -> O(n) time.
Tested and works (assuming the array is ordered already)
public static int[] noDups(int[] myArray) {
int dups = 0; // represents number of duplicate numbers
for (int i = 1; i < myArray.length; i++)
{
// if number in array after current number in array is the same
if (myArray[i] == myArray[i - 1])
dups++; // add one to number of duplicates
}
// create return array (with no duplicates)
// and subtract the number of duplicates from the original size (no NPEs)
int[] returnArray = new int[myArray.length - dups];
returnArray[0] = myArray[0]; // set the first positions equal to each other
// because it's not iterated over in the loop
int count = 1; // element count for the return array
for (int i = 1; i < myArray.length; i++)
{
// if current number in original array is not the same as the one before
if (myArray[i] != myArray[i-1])
{
returnArray[count] = myArray[i]; // add the number to the return array
count++; // continue to next element in the return array
}
}
return returnArray; // return the ordered, unique array
}
My previous answer to this problem with used an Integer List.
Not creating a new array will surely result in nulls all over the initial array. Therefore create a new array for storing the unique values from the initial array.
How do you check for unique values? Here's the pseudo code
uniq = null
loop(1..arraysize)
if (array[current] == uniq) skip
else store array[current] in next free index of new array; uniq = array[current]
end loop
Also as others mentioned get the array size by initial scan of array
uniq = null
count = 0
loop(1..arraysize)
if (array[current] == uniq) skip
else uniq = array[current] and count++
end loop
create new array of size count
public static int[] findDups(int[] myArray) {
int numOfDups = 0;
for (int i = 0; i < myArray.length-1; i++) {
if (myArray[i] == myArray[i+1]) {
numOfDups++;
}
}
int[] noDupArray = new int[myArray.length-numOfDups];
int last = 0;
int x = 0;
for (int i = 0; i < myArray.length; i++) {
if(last!=myArray[i]) {
last = myArray[i];
noDupArray[x++] = last;
}
}
return noDupArray;
}
public int[] noDups(int[] arr){
int j = 0;
// copy the items without the dups to res
int[] res = new int[arr.length];
for(int i=0; i<arr.length-2; i++){
if(arr[i] != arr[i+1]){
res[j] = arr[i];
j++;
}
}
// copy the last element
res[j]=arr[arr.length-1];
j++;
// now move the result into a compact array (exact size)
int[] ans = new int[j];
for(int i=0; i<j; i++){
ans[i] = res[i];
}
return ans;
}
First loop is O(n) and so is the second loop - which totals in O(n) as requested.
I have an array of size 1000. How can I find the indices (indexes) of the five maximum elements?
An example with setup code and my attempt are displayed below:
Random rand = new Random();
int[] myArray = new int[1000];
int[] maxIndices = new int[5];
int[] maxValues = new int[5];
for (int i = 0; i < myArray.length; i++) {
myArray[i] = rand.nextInt();
}
for (int i = 0; i < 5; i++) {
maxIndices[i] = i;
maxValues[i] = myArray[i];
}
for (int i = 0; i < maxIndices.length; i++) {
for (int j = 0; j < myArray.length; j++) {
if (myArray[j] > maxValues[i]) {
maxIndices[i] = j;
maxValues[i] = myArray[j];
}
}
}
for (int i = 0; i < maxIndices.length; i++) {
System.out.println("Index: " + maxIndices[i]);
}
I know the problem is that it is constantly assigning the highest maximum value to all the maximum elements. I am unsure how to remedy this because I have to preserve the values and the indices of myArray.
I don't think sorting is an option because I need to preserve the indices. In fact, it is the indices that I need specifically.
Sorry to answer this old question but I am missing an implementation which has all following properties:
Easy to read
Performant
Handling of multiple same values
Therefore I implemented it:
private int[] getBestKIndices(float[] array, int num) {
//create sort able array with index and value pair
IndexValuePair[] pairs = new IndexValuePair[array.length];
for (int i = 0; i < array.length; i++) {
pairs[i] = new IndexValuePair(i, array[i]);
}
//sort
Arrays.sort(pairs, new Comparator<IndexValuePair>() {
public int compare(IndexValuePair o1, IndexValuePair o2) {
return Float.compare(o2.value, o1.value);
}
});
//extract the indices
int[] result = new int[num];
for (int i = 0; i < num; i++) {
result[i] = pairs[i].index;
}
return result;
}
private class IndexValuePair {
private int index;
private float value;
public IndexValuePair(int index, float value) {
this.index = index;
this.value = value;
}
}
Sorting is an option, at the expense of extra memory. Consider the following algorithm.
1. Allocate additional array and copy into - O(n)
2. Sort additional array - O(n lg n)
3. Lop off the top k elements (in this case 5) - O(n), since k could be up to n
4. Iterate over the original array - O(n)
4.a search the top k elements for to see if they contain the current element - O(lg n)
So it step 4 is (n * lg n), just like the sort. The entire algorithm is n lg n, and is very simple to code.
Here's a quick and dirty example. There may be bugs in it, and obviously null checking and the like come into play.
import java.util.Arrays;
class ArrayTest {
public static void main(String[] args) {
int[] arr = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
int[] indexes = indexesOfTopElements(arr,3);
for(int i = 0; i < indexes.length; i++) {
int index = indexes[i];
System.out.println(index + " " + arr[index]);
}
}
static int[] indexesOfTopElements(int[] orig, int nummax) {
int[] copy = Arrays.copyOf(orig,orig.length);
Arrays.sort(copy);
int[] honey = Arrays.copyOfRange(copy,copy.length - nummax, copy.length);
int[] result = new int[nummax];
int resultPos = 0;
for(int i = 0; i < orig.length; i++) {
int onTrial = orig[i];
int index = Arrays.binarySearch(honey,onTrial);
if(index < 0) continue;
result[resultPos++] = i;
}
return result;
}
}
There are other things you can do to reduce the overhead of this operation. For example instead of sorting, you could opt to use a queue that just tracks the largest 5. Being ints they values would probably have to be boxed to be added to a collection (unless you rolled your own) which adds to overhead significantly.
a bit late in answering, you could also use this function that I wrote:
/**
* Return the indexes correspond to the top-k largest in an array.
*/
public static int[] maxKIndex(double[] array, int top_k) {
double[] max = new double[top_k];
int[] maxIndex = new int[top_k];
Arrays.fill(max, Double.NEGATIVE_INFINITY);
Arrays.fill(maxIndex, -1);
top: for(int i = 0; i < array.length; i++) {
for(int j = 0; j < top_k; j++) {
if(array[i] > max[j]) {
for(int x = top_k - 1; x > j; x--) {
maxIndex[x] = maxIndex[x-1]; max[x] = max[x-1];
}
maxIndex[j] = i; max[j] = array[i];
continue top;
}
}
}
return maxIndex;
}
My quick and a bit "think outside the box" idea would be to use the EvictingQueue that holds an maximum of 5 elements. You'd had to pre-fill it with the first five elements from your array (do it in a ascending order, so the first element you add is the lowest from the five).
Than you have to iterate through the array and add a new element to the queue whenever the current value is greater than the lowest value in the queue. To remember the indexes, create a wrapper object (a value/index pair).
After iterating through the whole array, you have your five maximum value/index pairs in the queue (in descending order).
It's a O(n) solution.
Arrays.sort(myArray), then take the final 5 elements.
Sort a copy if you want to preserve the original order.
If you want the indices, there isn't a quick-and-dirty solution as there would be in python or some other languages. You sort and scan, but that's ugly.
Or you could go objecty - this is java, after all.
Make an ArrayMaxFilter object. It'll have a private class ArrayElement, which consists of an index and a value and has a natural ordering by value. It'll have a method which takes a pair of ints, index and value, creates an ArrayElement of them, and drops them into a priority queue of length 5. (or however many you want to find). Submit each index/value pair from the array, then report out the values remaining in the queue.
(yes, a priority queue traditionally keeps the lowest values, but you can flip this in your implementation)
Here is my solution. Create a class that pairs an indice with a value:
public class IndiceValuePair{
private int indice;
private int value;
public IndiceValuePair(int ind, int val){
indice = ind;
value = val;
}
public int getIndice(){
return indice;
}
public int getValue(){
return value;
}
}
and then use this class in your main method:
public static void main(String[] args){
Random rand = new Random();
int[] myArray = new int[10];
IndiceValuePair[] pairs = new IndiceValuePair[5];
System.out.println("Here are the indices and their values:");
for(int i = 0; i < myArray.length; i++) {
myArray[i] = rand.nextInt(100);
System.out.println(i+ ": " + myArray[i]);
for(int j = 0; j < pairs.length; j++){
//for the first five entries
if(pairs[j] == null){
pairs[j] = new IndiceValuePair(i, myArray[i]);
break;
}
else if(pairs[j].getValue() < myArray[i]){
//inserts the new pair into its correct spot
for(int k = 4; k > j; k--){
pairs[k] = pairs [k-1];
}
pairs[j] = new IndiceValuePair(i, myArray[i]);
break;
}
}
}
System.out.println("\n5 Max indices and their values");
for(int i = 0; i < pairs.length; i++){
System.out.println(pairs[i].getIndice() + ": " + pairs[i].getValue());
}
}
and example output from a run:
Here are the indices and their values:
0: 13
1: 71
2: 45
3: 38
4: 43
5: 9
6: 4
7: 5
8: 59
9: 60
5 Max indices and their values
1: 71
9: 60
8: 59
2: 45
4: 43
The example I provided only generates ten ints with a value between 0 and 99 just so that I could see that it worked. You can easily change this to fit 1000 values of any size. Also, rather than run 3 separate for loops, I checked to see if the newest value I add is a max value right after I add to to myArray. Give it a run and see if it works for you