Reversing araylist of integers manually - java

public static ArrayList<Integer> reverse (ArrayList<Integer> n) {
ArrayList<Integer> result = new ArrayList<Integer>();
for(int i = 0; i < n.size(); i++) {
int j = n.size() - i - 1;
result.add(i, n.get(j));
}
return result;
}
but if i enter an array 1,2,3,4,5,6,7,8,9,10
the result is 10,9,8,7,6,5,4,3,2,10
Where is my mistake?

Actually, what you have there works fine. But you can simplify your for-loop by iterating 'backwards':
for(int i = n.size() - 1 ; i >= 0 ; i--)
result.add(n.get(i));
Oh, and one more thing I should mention. When you declare the list result, you might want to specify its capacity, since you know what it will be. i.e.:
ArrayList<Integer> result = new ArrayList<Integer>(n.size());

Uses n.size() / 2 swaps (the fewest possible) and runs in linear time.
public static ArrayList<Integer> reverse (ArrayList<Integer> n)
{
for (int i = 0, j = n.size() - 1, t; i <= size / 2; ++i, --j)
{
t = n.get(i);
n.set(i, n.get(j));
n.set(j, t);
}
return n;
}

Collections.reverse(arrayList);
In case you still want to go for a manual one,
public ArrayList<Integer> reverse(ArrayList<Integer> arrayList) {
ArrayList<Integer> result = (ArrayList<Integer>)list.clone();
for (int start=0,end=result.size()-1;start<end;start++,end--) {
swap(result,start,end) ;
}
return result;
}
public void swap(ArrayList<Integer> temp, int front, int back) {
Integer i = temp.set(front,temp.get(back)) ;
temp.set(back, i) ;
}

It doesn't work for lists with even numbers of items

Related

Having a casting issue with traveling salesperson using a greedy algorithm

I figure I have the general idea down for how to solve the algorithm but the implementation seems to elude me. What I have thus far is this:
public class GreedySalesman {
public static int[] greedySalesmanSolution(int[][] distances) {
List cityList = new ArrayList();
for(int[] array: distances) {
cityList.add(Arrays.asList(array));
}
List<Integer> initialResult = new ArrayList();
initialResult.add(0);
List<Integer> finalResult = findMinDistance(cityList, cityList, initialResult, 0);
/*int finalResultArray = new int[finalResult.size()+1];
int i = 0;
while (!(finalResult.isEmpty)) {
finalResultArray[i] = finalResult.poll();
i++;
}
return finalResultArray;
*/
return null;
}
public static List<Integer> findMinDistance(List<List<Integer>> initialCityInput, List<List<Integer>> cityInput, List<Integer> distanceResult, int index) {
if(cityInput.isEmpty()) {
distanceResult.add(0);
return distanceResult;
}
int min = Collections.min(initialCityInput.get(index));
List<Integer> city = initialCityInput.get(index);
index = city.indexOf(min);
distanceResult.add(index);
cityInput.remove(city);
return findMinDistance(initialCityInput,cityInput,distanceResult,index);
}
}
That is, the algorithm will take an two dimensional array of ints as an input, then make a List cityList referring to distances, then pass it into findMinDistance. The commented out part is where the result from findMinDistance will be converted into an array of ints and returned as finalResultArray but that part is not important yet.
findMinDistance will take in a two dimensional list of Integers twice, a List of Integers that will become the result and an int representing an index.
The function will return the distanceResult when cityInput has been emptied. Otherwise it will start with the first city based on the index, get the minimum distance from that List and its index and add the index to the distanceResult.
Once that has been done, the city will be removed from the cityInput and the program will go into recursion until cityInput has been emptied.
The issue I am getting currently is
I cannot be cast to java.lang.Integer
at
int min = Collections.min(initialCityInput.get(index));
And in main upon trying to run the program with some test data.
Any help will be appreciated.
======
Edit:
I made some changes to my code
public class GreedyTSP {
public int[] greedySalesmanSolution(int[][] distances) {
List<List<Integer>> cityList = new ArrayList();
List<List<Integer>> initialCityList = new ArrayList();
int iLength = distances.length;
for (int i = 0; i < iLength; ++i) {
int jLength = distances[0].length;
cityList.add(new ArrayList(jLength));
initialCityList.add(new ArrayList(jLength));
for (int j = 0; j < jLength; ++j) {
cityList.get(i).add(distances[i][j]);
initialCityList.get(i).add(distances[i][j]);
}
}
List<Integer> initialResult = new ArrayList();
initialResult.add(0);
List<Integer> finalResult = findMinDistance(initialCityList, cityList, initialResult, 0);
int[] finalResultArray = new int[finalResult.size()];
Iterator<Integer> iterator = finalResult.iterator();
for (int i = 0; i < finalResultArray.length; i++){
finalResultArray[i] = iterator.next().intValue();
}
return finalResultArray;
}
public List<Integer> findMinDistance(List<List<Integer>> initialCityInput, List<List<Integer>> cityInput, List<Integer> distanceResult, int initialIndex) {
if(cityInput.isEmpty()) {
distanceResult.add(0);
return distanceResult;
}
List<Integer> city = initialCityInput.get(initialIndex);
Integer min = findMin(city, distanceResult, initialIndex);
int resultIndex = city.indexOf(min);
distanceResult.add(resultIndex);
cityInput.remove(city);
return findMinDistance(initialCityInput,cityInput,distanceResult,resultIndex);
}
public Integer findMin(List<Integer> city, List<Integer> distanceResult, int inputIndex) {
Integer min = Integer.MAX_VALUE;
for(int i = 0; i < city.size();i++) {
if (city.get(i) > inputIndex && city.get(i) < min) min = city.get(i);
}
int resultIndex = city.indexOf(min);
if(distanceResult.contains(resultIndex)) {
return findMin(city, distanceResult, inputIndex);
}
return min;
}
}
Im not having any cast errors at the moment but it seems that the parts of my program dealing with recursion are causing StackOverflowError-s. I've been messing with this thing for literally 16 hours now and I'm all out of ideas as to why. Any ideas?
The problem with your casting is the following
List<List<Integer>> initialCityInput is a List containing Lists with integers.
Therefore initalCityInput.get(index) returns a List not an Int, which cannot be cast to int.
Well, I looked around a bit and I was basically overcomplicating the task through using multidimensional arraylists. I changed the code quite a bit:
public class GreedyTSP {
public static int[] greedySolution(int[][] adjacencyMatrix) {
List<Integer> visitedCities = new ArrayList<>();
int min = Integer.MAX_VALUE;
int startLocation = 0;
int tempStartLocation = 0;
int[] resultArray = new int[adjacencyMatrix.length+1];
visitedCities.add(0);
while(visitedCities.size() < adjacencyMatrix.length ){
for(int i = 0; i < adjacencyMatrix.length; i++){
if(!visitedCities.contains(i) && adjacencyMatrix[startLocation][i] < min){
min = adjacencyMatrix[startLocation][i];
tempStartLocation = i;
}
}
startLocation = tempStartLocation;
visitedCities.add(tempStartLocation);
min = Integer.MAX_VALUE;
}
visitedCities.add(0);
for(int i = 0; i < resultArray.length; i++){
int temp = visitedCities.get(i);
resultArray[i] = temp;
}
return resultArray;
}
}
This will solve the task using a greedy algorithm

Java - iterate through ArrayList for only increasing elements

Here is my ArrayList:
[1,2,1,0,3,4]
I'm trying to return this:
[1,2,3,4]
Here is my current attempt:
for (int i = 0; i < myArray.size() - 1; i++) {
if (myArray.get(i) < myArray.get(i + 1)) {
System.out.println("Increasing sequence...");
}
}
However, this is not returning the desired output, any ideas?
You'll have to maintain an index (or value) of the last element that you had printed and store it in some variable. Then, you'll have to use the stored element for every new element and check if is greater than the stored element.
As you have mentioned, the first element has to be anyway printed, no matter what.
Something like this might work:
List<Integer> myArray = Arrays.asList(new Integer[]{1,2,1,0,3,4});
System.out.println(myArray.get(0));
int prevPrint = myArray.get(0);
for (int i = 1; i < myArray.size();i++) {
if (myArray.get(i) > prevPrint) {
System.out.println(myArray.get(i));
prevPrint = myArray.get(i);
}
}
The reason why your program was failing was because you were comparing the adjacent two values only and it was possible that you might have already printed a value which is greater than any of the two adjacent values.
A similar question, but a totally different approach (LIS) exists and can be found here
A slight variant on Parijat's answer to avoid repeating the System.out.println:
for (int j = 0; j < myArray.size();) {
System.out.println(myArray.get(j));
int start = j;
do {
++j;
while (j < myArray.size() && myArray.get(j) <= myArray.get(start));
}
Try this,
public static List<Integer> findIncreasingOrder(int[] nums) {
List<Integer> result = new ArrayList<>();
int MAX = Integer.MIN_VALUE;
for (int i = 0; i < nums.length; i++) {
int value = nums[i];
if (value >MAX){
System.out.println(value);
MAX = value;
result.add(value);
}
}
return result;
}

Find "Missing" Integer in a Java Array

Given an array A[] of length n, find a "missing" number k such that:
k is not in A
0<=k<=n
I've seen similar questions asked where the A[] contains numbers 1 to n with one number missing, but in this question, A[] can contain any numbers. I need a solution in O(n) time. For example,
A = {1,2,3} -> 0
A = {0,1,2} -> 3
A = {2,7,4,1,6,0,5,-3} -> 3,8
I've gotten as far as checking if 0 or n are in the array, and if not, return 0 or n, but I cannot seem to think of any other solution. This problem seems considerably more difficult given the fact that A can contain any numbers and not necessarily numbers 1 to n or something like that.
Linearly iterate over the array and "cross out" every number you encounter. Then iterate of that listed of crossed out numbers again and see which one is missing.
public static int getMissingNumber(int[] A)
{
int n = A.length;
boolean[] numbersUsed = new boolean[n + 1]; //Because the definition says 0 <= k <= n, so k = n is also possible.
for(int k = 0; k < n; k++)
{
if(A[k] <= n && A[k] >= 0) //No negative numbers!
numbersUsed[A[k]] = true;
}
for(int k = 0; k <= n; k++)
{
if(numbersUsed[k] == false)
return k;
}
return -1; //nothing found
}
Complexity is 2*n because of the two for loops, giving overall complexity O(n).
Simple approach:
initialize a set with all the values you need. (In your case number 0 to n)
iterate over your arry and remove the number from the set
at the end the set is giving you the missing entries.
If you know that exactly one number is missing, there is a simple solution using xor.
static int missing(int[] arr) {
int result = 0;
for (int i = 0; i < arr.length; i++)
result ^= (i + 1) ^ arr[i];
return result;
}
If there may be more than one number missing you can return a Set like this:
static Set<Integer> missing(int[] arr) {
Set<Integer> set = new HashSet<>();
for (int i = 0; i <= arr.length; i++)
set.add(i);
for (int a : arr)
set.remove(a);
return set;
}
Here is a solution that utilizes one loop. That's if we choose to ignore what Arrays.sort does
import java.util.Arrays;
class Solution {
public int solution(int[] A) {
Arrays.sort(A);
int min = 1;
for (int i = 0; i < A.length; i++){
if(A[i]== min){
min++;
}
}
min = ( min <= 0 ) ? 1:min;
return min;
}
}
class Missing{
public static void main(String[] args) {
int arr[]={1,2,4,5,6,7,9};
System.out.println(missingNumberArray(arr));
}
public static int missingNumberArray(int [] a) {
int result=0;
for(int i=0;i<a.length-1;i++){
if(a[i+1]-a[i]!=1){
result=a[i]+1;
}
}
return result;
}
}
//output:missing element is:3
// missing element is:8

Creating an Array with the same numbers from an old one but without repetitions

So I created an array with random numbers, i printed and counted the repeated numbers, now I just have to create a new array with the same numbers from the first array but without any repetitions. Can't use ArrayList by the way.
What I have is.
public static void main(String[] args) {
Random generator = new Random();
int aR[]= new int[20];
for(int i=0;i<aR.length;i++){
int number=generator.nextInt(51);
aR[i]=number;
System.out.print(aR[i]+" ");
}
System.out.println();
System.out.println();
int countRep=0;
for(int i=0;i<aR.length;i++){
for(int j=i+1;j<aR.length-1;j++){
if(aR[i]==aR[j]){
countRep++;
System.out.println(aR[i]+" "+aR[j]);
break;
}
}
}
System.out.println();
System.out.println("Repeated numbers: "+countRep);
int newaR[]= new int[aR.length - countRep];
}
Can someone help?
EDIT: Can't really use HashSet either. Also the new array needs to have the correct size.
Using Java 8 and streams you can do the following:
int[] array = new int[1024];
//fill array
int[] arrayWithoutDuplicates = Arrays.stream(array)
.distinct()
.toArray();
This will:
Turn your int[] into an IntStream.
Filter out all duplicates, so retaining distinct elements.
Save it in a new array of type int[].
Try:
Set<Integer> insertedNumbers = new HashSet<>(newaR.length);
int index = 0;
for(int i = 0 ; i < aR.length ; ++i) {
if(!insertedNumbers.contains(aR[i])) {
newaR[index++] = aR[i];
}
insertedNumbers.add(aR[i]);
}
One possible approach is to walk through the array, and for each value, compute the index at which it again occurs in the array (which is -1 if the number does not occur again). The number of values which do not occur again is the number of unique values. Then collect all values from the array for which the corresponding index is -1.
import java.util.Arrays;
import java.util.Random;
public class UniqueIntTest
{
public static void main(String[] args)
{
int array[] = createRandomArray(20, 0, 51);
System.out.println("Array " + Arrays.toString(array));
int result[] = computeUnique(array);
System.out.println("Result " + Arrays.toString(result));
}
private static int[] createRandomArray(int size, int min, int max)
{
Random random = new Random(1);
int array[] = new int[size];
for (int i = 0; i < size; i++)
{
array[i] = min + random.nextInt(max - min);
}
return array;
}
private static int[] computeUnique(int array[])
{
int indices[] = new int[array.length];
int unique = computeIndices(array, indices);
int result[] = new int[unique];
int index = 0;
for (int i = 0; i < array.length; i++)
{
if (indices[i] == -1)
{
result[index] = array[i];
index++;
}
}
return result;
}
private static int computeIndices(int array[], int indices[])
{
int unique = 0;
for (int i = 0; i < array.length; i++)
{
int value = array[i];
int index = indexOf(array, value, i + 1);
if (index == -1)
{
unique++;
}
indices[i] = index;
}
return unique;
}
private static int indexOf(int array[], int value, int offset)
{
for (int i = offset; i < array.length; i++)
{
if (array[i] == value)
{
return i;
}
}
return -1;
}
}
This sounds like a homework question, and if it is, the technique that you should pick up on is to sort the array first.
Once the array is sorted, duplicate entries will be adjacent to each other, so they are trivial to find:
int[] numbers = //obtain this however you normally would
java.util.Arrays.sort(numbers);
//find out how big the array is
int sizeWithoutDuplicates = 1; //there will be at least one entry
int lastValue = numbers[0];
//a number in the array is unique (or a first duplicate)
//if it's not equal to the number before it
for(int i = 1; i < numbers.length; i++) {
if (numbers[i] != lastValue) {
lastValue = i;
sizeWithoutDuplicates++;
}
}
//now we know how many results we have, and we can allocate the result array
int[] result = new int[sizeWithoutDuplicates];
//fill the result array
int positionInResult = 1; //there will be at least one entry
result[0] = numbers[0];
lastValue = numbers[0];
for(int i = 1; i < numbers.length; i++) {
if (numbers[i] != lastValue) {
lastValue = i;
result[positionInResult] = i;
positionInResult++;
}
}
//result contains the unique numbers
Not being able to use a list means that we have to figure out how big the array is going to be in a separate pass — if we could use an ArrayList to collect the results we would have only needed a single loop through the array of numbers.
This approach is faster (O(n log n) vs O (n^2)) than a doubly-nested loop through the array to find duplicates. Using a HashSet would be faster still, at O(n).

Radix sort in java help

Hi i need some help to improve my code. I am trying to use Radixsort to sort array of 10 numbers (for example) in increasing order.
When i run the program with array of size 10 and put 10 random int numbers in like
70
309
450
279
799
192
586
609
54
657
i get this out:
450
309
192
279
54
192
586
657
54
609
Don´t see where my error is in the code.
class IntQueue
{
static class Hlekkur
{
int tala;
Hlekkur naest;
}
Hlekkur fyrsti;
Hlekkur sidasti;
int n;
public IntQueue()
{
fyrsti = sidasti = null;
}
// First number in queue.
public int first()
{
return fyrsti.tala;
}
public int get()
{
int res = fyrsti.tala;
n--;
if( fyrsti == sidasti )
fyrsti = sidasti = null;
else
fyrsti = fyrsti.naest;
return res;
}
public void put( int i )
{
Hlekkur nyr = new Hlekkur();
n++;
nyr.tala = i;
if( sidasti==null )
f yrsti = sidasti = nyr;
else
{
sidasti.naest = nyr;
sidasti = nyr;
}
}
public int count()
{
return n;
}
public static void radixSort(int [] q, int n, int d){
IntQueue [] queue = new IntQueue[n];
for (int k = 0; k < n; k++){
queue[k] = new IntQueue();
}
for (int i = d-1; i >=0; i--){
for (int j = 0; j < n; j++){
while(queue[j].count() != 0)
{
queue[j].get();
}
}
for (int index = 0; index < n; index++){
// trying to look at one of three digit to sort after.
int v=1;
int digit = (q[index]/v)%10;
v*=10;
queue[digit].put(q[index]);
}
for (int p = 0; p < n; p++){
while(queue[p].count() != 0) {
q[p] = (queue[p].get());
}
}
}
}
}
I am also thinking can I let the function take one queue as an
argument and on return that queue is in increasing order? If so how?
Please help. Sorry if my english is bad not so good in it.
Please let know if you need more details.
import java.util.Random;
public class RadTest extends IntQueue {
public static void main(String[] args)
{
int [] q = new int[10];
Random r = new Random();
int t = 0;
int size = 10;
while(t != size)
{
q[t] = (r.nextInt(1000));
t++;
}
for(int i = 0; i!= size; i++)
{
System.out.println(q[i]);
}
System.out.println("Radad: \n");
radixSort(q,size,3);
for(int i = 0; i!= size; i++)
{
System.out.println(q[i]);
}
}
}
Hope this is what you were talking about...
Thank you for your answer, I will look into it. Not looking for someone to solve the problem for me. Looking for help and Ideas how i can solve it.
in my task it says:
Implement a radix sort function for integers that sorts with queues.
The function should take one queue as an
argument and on return that queue should contain the same values in ascending
order You may assume that the values are between 0 and 999.
Can i put 100 int numbers on my queue and use radixsort function to sort it or do i need to put numbers in array and then array in radixsort function which use queues?
I understand it like i needed to put numbers in Int queue and put that queue into the function but that has not worked.
But Thank for your answers will look at them and try to solve my problem. But if you think you can help please leave comment.
This works for the test cases I tried. It's not entirely well documented, but I think that's okay. I'll leave it to you to read it, compare it to what you're currently doing, and find out why what you have might be different than mine in philosophy. There's also other things that are marked where I did them the "lazy" way, and you should do them a better way.
import java.util.*;
class Radix {
static int[] radixSort(int[] arr) {
// Bucket is only used in this method, so I declare it here
// I'm not 100% sure I recommend doing this in production code
// but it turns out, it's perfectly legal to do!
class Bucket {
private List<Integer> list = new LinkedList<Integer>();
int[] sorted;
public void add(int i) { list.add(i); sorted = null;}
public int[] getSortedArray() {
if(sorted == null) {
sorted = new int[list.size()];
int i = 0;
for(Integer val : list) {
sorted[i++] = val.intValue(); // probably could autobox, oh well
}
Arrays.sort(sorted); // use whatever method you want to sort here...
// Arrays.sort probably isn't allowed
}
return sorted;
}
}
int maxLen = 0;
for(int i : arr) {
if(i < 0) throw new IllegalArgumentException("I don't deal with negative numbers");
int len = numKeys(i);
if(len > maxLen) maxLen = len;
}
Bucket[] buckets = new Bucket[maxLen];
for(int i = 0; i < buckets.length; i++) buckets[i] = new Bucket();
for(int i : arr) buckets[numKeys(i)-1].add(i);
int[] result = new int[arr.length];
int[] posarr = new int[buckets.length]; // all int to 0
for(int i = 0; i < result.length; i++) {
// get the 'best' element, which will be the most appropriate from
// the set of earliest unused elements from each bucket
int best = -1;
int bestpos = -1;
for(int p = 0; p < posarr.length; p++) {
if(posarr[p] == buckets[p].getSortedArray().length) continue;
int oldbest = best;
best = bestOf(best, buckets[p].getSortedArray()[posarr[p]]);
if(best != oldbest) {
bestpos = p;
}
}
posarr[bestpos]++;
result[i] = best;
}
return result;
}
static int bestOf(int a, int b) {
if(a == -1) return b;
// you'll have to write this yourself :)
String as = a+"";
String bs = b+"";
if(as.compareTo(bs) < 0) return a;
return b;
}
static int numKeys(int i) {
if(i < 0) throw new IllegalArgumentException("I don't deal with negative numbers");
if(i == 0) return 1;
//return (i+"").length(); // lame method :}
int len = 0;
while(i > 0) {
len++;
i /= 10;
}
return len;
}
public static void main(String[] args) {
int[] test = {1, 6, 31, 65, 143, 316, 93, 736};
int[] res = radixSort(test);
for(int i : res) System.out.println(i);
}
}
One thing that looks strange:
for (int p = 0; p < n; p++){
while(queue[p].count() != 0) {
q[p] = (queue[p].get());
}
}
Is p supposed to be the index in q, which ranges from 0 to n-1, or in queue, which ranges from 0 to 9? It is unlikely to be both ...
Another:
for (int index = 0; index < n; index++){
// trying to look at one of three digit to sort after.
int v=1;
int digit = (q[index]/v)%10;
v*=10;
queue[digit].put(q[index]);
}
Why are you multiplying v by 10, only to overwrite it by v = 1 in the next iteration? Are you aware than v will always be one, and you will thus look at the same digit in every iteration?
Well I don't think I can help without almost posting the solution (just giving hints is more exhausting and I'm a bit tired, sorry), so I'll just contribute a nice little fuzz test so you can test your solution. How does that sound? :-)
Coming up with a good fuzztester is always a good idea if you're implementing some algorithm. While there's no 100% certainty if that runs with your implementation chances are it'll work (radix sort doesn't have any strange edge cases I'm aware of that only happen extremely rarely)
private static void fuzztest() throws Exception{
Random rnd = new Random();
int testcnt = 0;
final int NR_TESTS = 10000;
// Maximum size of array.
final int MAX_DATA_LENGTH = 1000;
// Maximum value allowed for each integer.
final int MAX_SIZE = Integer.MAX_VALUE;
while(testcnt < NR_TESTS){
int len = rnd.nextInt(MAX_DATA_LENGTH) + 1;
Integer[] array = new Integer[len];
Integer[] radix = new Integer[len];
for(int i = 0; i < len; i++){
array[i] = rnd.nextInt(MAX_SIZE);
radix[i] = new Integer(array[i]);
}
Arrays.sort(array);
sort(radix); // use your own sort function here.
for(int i = 0; i < len; i++){
if(array[i].compareTo(radix[i]) != 0){
throw new Exception("Not sorted!");
}
}
System.out.println(testcnt);
testcnt++;
}

Categories