Related
question: Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twice and return the new length.
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
My solution: This code is always missing on one index no matter what. Can someone please help me why ? For example my example input is supposed to return 6,but it returns 5.
int[] arr2= {1,1,1,2,3,4,4};
int i=findDupsMedium(arr2);
System.out.println(i);
static int findDupsMedium(int[] arr) {
int index=0;
if(arr.length>1) {
for(int i=0;i<2;i++) {
arr[index++]=arr[i];
}
}
//System.out.println("index:" + index);
for(int ii=2;ii<arr.length;ii++ ) {
int diff=ii-2;
if(arr[ii] != arr[diff]) {
arr[index++]=arr[ii];
}
}
return index;
}
Your approach is ok, but missing some certain parts.
Here is a little bit dirty solution, it works for consecutive duplicates.
If input array has duplicates in different places, you have to implement another for loop.
static int findDupsMedium(int[] arr) {
int count=0;
//used for extracting duplicates from the length of array
int extract=0;
if(arr.length>1) {
// this is for having a comparison withot getting outOfBounds;
int lastItem=0;
for(int i=0; i<arr.length; i++) {
//If we had 2 duplicates and new one is the same with previous one, remove
if(count == 2 && lastItem == arr[i]){
//if end of the array has duplicate, make it "-1"
if(i==arr.length-1){
arr[i]=-1;
}
else{
extract++; //we found a duplicate
lastItem = arr[i];
//shift it
for(int j=i;j<arr.length-1;j++){
arr[j]=arr[j+1];
}
}
//printArray(arr);
count = 0;
}
else{
if(arr[i+1]==arr[i]){
count++;
lastItem = arr[i];
}
}
}
}
return arr.length - extract;
}
To do this you need to keep track of the length of the array as it changes as well as when to update the main loop's index.
A boolean flag is also used to keep track of when a series of duplicates occur.
public static int findDupsMedium(int[] arr2) {
int size = arr2.length;
boolean foundFirstDuplicate = false;
for (int i = 0; i < arr2.length - 1; i++) {
for (int k = i + 1; k < size;) {
if (arr2[i] == arr2[k]) {
if (foundFirstDuplicate) {
// If we're here, this must be third
// duplicate in a row so copy up the array
// overwriting the third dupe.
for (int g = k; g < arr2.length - 1; g++) {
arr2[g] = arr2[g + 1];
}
i--; // and readjust outer loop to stay in
// position
// and effective size of array is one smaller
// so adjust that
size--;
}
// set first time a duplicate is found and keep this set
// until no more duplicates
foundFirstDuplicate = true;
break;
}
// no third or more duplicate so set to false
foundFirstDuplicate = false;
break;
}
}
return size;
}
To verify it works ok, add the folowing method
static void display(int[] a, int size) {
int[] t = Arrays.copyOf(a, size);
System.out.println(Arrays.toString(t));
}
And call the methods as follows:
int[] arr2 = { 1, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5
};
int size = findDupsMedium(arr2);
display(arr2, size);
Given an array of ints, I want to rearrange it alternately i.e. first element should be minimum, second should be maximum, third second-minimum, fourth second-maximum and so on...
I'm completely lost here...
Another method that doesn't require the space of three separate arrays but isn't as complex as reordering in place would be to sort the original array and then create a single new array. Then start iterating with a pointer to the current i-th index of the new array and pointers starting at the 0-th index and the last index of the sorted array.
public class Foo {
public static void main(String[] args) {
// Take your original array
int[] arr = { 1, 4, 5, 10, 6, 8, 3, 9 };
// Use the Arrays sort method to sort it into ascending order (note this mutates the array instance)
Arrays.sort(arr);
// Create a new array of the same length
int[] minMaxSorted = new int[arr.length];
// Iterate through the array (from the left and right at the same time)
for (int i = 0, min = 0, max = arr.length - 1; i < arr.length; i += 2, min++, max--) {
// the next minimum goes into minMaxSorted[i]
minMaxSorted[i] = arr[min];
// the next maximum goes into minMaxSorted[i + 1] ... but
// guard against index out of bounds for odd number arrays
if (i + 1 < minMaxSorted.length) {
minMaxSorted[i + 1] = arr[max];
}
}
System.out.println(Arrays.toString(minMaxSorted));
}
}
Hint:
Create two new arrays, 1st is sorted in assenting order and other is in descending order. Than select 1st element from 2nd array and 1st element from 1st array, repeat this selection until you reach half of both 1st and second array. and you will get your desired array.
Hope this will help you.
The approach in #Kaushal28's answer is the best approach for a beginner. It requires more space (2 extra copies of the array) but it is easy to understand and code.
An advanced programmer might consider sorting the array once, and then rearranging the elements. It should work, but the logic is complicated.
Hint: have you ever played "Clock Patience"?
This solution is based on Aaron Davis solution. I tried to make the looping easier to follow:
public class AltSort {
//list of array elements that were sorted
static Set<Integer> indexSorted = new HashSet<Integer>();
public static void main (String[] args) throws java.lang.Exception
{
//test case
int[] array = new int[]{7,22,4,67,5,11,-9,23,48, 3, 73, 1, 10};
System.out.println(Arrays.toString(altSort(array)));
//test case
array = new int[]{ 1, 4, 5, 10, 6, 8, 3, 9 };
System.out.println(Arrays.toString(altSort(array)));
}
private static int[] altSort(int[] array) {
if((array == null) || (array.length == 0)) {
System.err.println("Empty or null array can not be sorted.");
}
Arrays.sort(array);
//returned array
int[] sortedArray = new int[array.length];
int firstIndex = 0, lastIndex = array.length-1;
for (int i = 0; i < array.length; i++) {
if((i%2) == 0) { //even indices
sortedArray[i] = array[firstIndex++];
}
else {
sortedArray[i] = array[lastIndex --];
}
}
return sortedArray;
}
}
Here is another alternative: monitor the indices that have been sorted, and search the rest for the next min / max:
import java.util.Arrays;
import java.util.Set;
/**
* Demonstrates an option for sorting an int[] array as requested,
* by keeping a list of the array indices that has been sorted, and searching
* for the next min / max.
* This code is not optimal nor robust. It serves a demo for this option only.
*
*/
public class AltSort {
//list of array elements that were sorted
static Set<Integer> indexSorted ;
public static void main (String[] args) throws java.lang.Exception {
//test case
int[] array = new int[]{7,22,4,67,5,11,-9,23,48, 3, 73, 1, 10};
System.out.println(Arrays.toString(altSort2(array)));
//test case
array = new int[]{ 1, 4, 5, 10, 6, 8, 3, 9 };
System.out.println(Arrays.toString(altSort2(array)));
}
private static int[] altSort2(int[] array) {
if((array == null) || (array.length == 0)) {
System.err.println("Empty or null array can not be sorted.");
}
//returned array
int[] sortedArray = new int[array.length];
//flag indicating wether to look for min or max
boolean lookForMin = true;
int index = 0;
while(index < array.length) {
if(lookForMin) {
sortedArray[index] = lookForArrayMin(array);
}else {
sortedArray[index] = lookForArrayMax(array);
}
index++;
//alternate look for min / look for max
lookForMin = ! lookForMin;
}
return sortedArray;
}
private static int lookForArrayMin(int[] array) {
int minValue = Integer.MAX_VALUE;
int minValueIndex = 0;
for( int i =0; i< array.length; i++ ){
//if array[i] is min and was not sorted before, keep it as min
if( (array[i]< minValue) && ! indexSorted.contains(i) ) {
minValue = array[i]; //keep min
minValueIndex = i; //keep min index
}
}
//add the index to the list of sorted indices
indexSorted.add(minValueIndex);
return minValue;
}
private static int lookForArrayMax(int[] array) {
int maxValue = Integer.MIN_VALUE; //max value
int maxValueIndex = 0; //index of max value
for( int i =0; i< array.length; i++ ){
//if array[i] is max and was not sorted before, keep it as max
if( (array[i] > maxValue) && ! indexSorted.contains(i)) {
maxValue = array[i]; //keep max
maxValueIndex = i; //keep max index
}
}
//add the index to the list of sorted indices
indexSorted.add(maxValueIndex);
return maxValue;
}
}
Please read the question before marking it as duplicate
I have written following code to remove duplicates from array without using Util classes but now I am stuck
public class RemoveDups{
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45, };
int temp;
for (int i : a) {
for (int j = 0; j < a.length - 1; j++) {
if (a[j] > a[j + 1]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
a = removeDups(a);
for (int i : a) {
System.out.println(i);
}
}
private static int[] removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
}
}
return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
and now the output is
1
2
3
4
5
6
45
52
0
0
0
0
0
0
0
0
0
0
Here my problem is
My code is not working in case of 0s
I am not able to understand how sorting an array can reduce time of execution
Is there any way to remove elements from array without using Util classes I know one way to remove convert array into list and then remove but for that also we need Util classes is there any way to implement by myself.
Since the numbers you deal with are limited to a small range you can remove duplicates by a simple "counting sort": mark the numbers you have found in a set-like data structure and then go over the data structure. An array of boolean works just fine, for less memory usage you could create a basic bitset or hash table. If n is the number of elements in the array and m is the size of the range, this algorithm will have O(n+m) complexity.
private static int[] removeDups(int[] a, int maxA) {
boolean[] present = new boolean[maxA+1];
int countUnique = 0;
for (int i : a) {
if (!present[i]) {
countUnique++;
present[i] = true;
}
}
int[] result = new int[countUnique];
int j = 0;
for (int i=0; i<present.length; i++) {
if (present[i]) result[j++] = i;
}
return result;
}
I am not able to understand how sorting an array can reduce time of execution
In a sorted array you can detect duplicates in a single scan, taking O(n) time. Since sorting is faster than checking each pair - O(n log n) compared to O(n²) time complexity - it would be faster to sort the array instead of using the naive algorithm.
As you are making the result array of the same length as array a
so even if you put only unique items in it, rest of the blank items will have the duplicate values in them which is 0 for int array.
Sorting will not help you much, as you code is searching the whole array again and again for the duplicates. You need to change your logic for it.
You can put some negative value like -1 for all the array items first in result array and then you can easily create a new result array say finalResult array from it by removing all the negative values from it, It will also help you to remove all the zeroes.
In java , arrays are of fixed length. Once created, their size can't be changed.
So you created an array of size18.
Then after you applied your logic , some elements got deleted. But array size won't change. So even though there are only 8 elements after the duplicate removal, the rest 10 elements will be auto-filled with 0 to keep the size at 18.
Solution ?
Store the new list in another array whose size is 8 ( or whatever, calculate how big the new array should be)
Keep a new variable to point to the end of the last valid element, in this case the index of 52. Mind you the array will still have the 0 values, you just won't use them.
I am not able to understand how sorting an array can reduce time of execution
What ? You sort an array if you need it to be sorted. Nothing else. Some algorithm may require the array to be sorted or may work better if the array is sorted. Depends on where you are using the array. In your case, the sorting will not help.
As for your final question , you can definitely implement your own duplicate removal by searching if an element exists more than once and then deleting all the duplicates.
My code is not working in case of 0
There were no zeroes to begin with in your array. But because its an int[], after the duplicates are removed the remaining of the indexes are filled with 0. That's why you can see a lot of zeroes in your array. To get rid of those 0s, you need to create another array with a lesser size(size should be equal to the no. of unique numbers you've in your array, excluding 0).
If you can sort your array(I see that its already sorted), then you could either bring all the zeroes to the front or push them to the last. Based on that, you can iterate the array and get the index from where the actual values start in the array. And, then you could use Arrays.copyOfRange(array, from, to) to create a copy of the array only with the required elements.
try this
package naveed.workingfiles;
public class RemoveDups {
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45, };
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i=0;i<count;i++) {
System.out.println(result[i]);
}
// return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
public class RemoveDups {
public static void main(String[] args) {
int[] a = { 1, 2, 0, 3, 1,0, 3, 6, 2};
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
boolean zeroExist = false;
for (int i : a) {
if(i==0 && !zeroExist){
result[j++] = i;
zeroExist = true;
count++;
}
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i=0;i<count;i++) {
System.out.println(result[i]);
}
// return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
// It works even Array contains 'Zero'
class Lab2 {
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45 };
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i = 0; i < count; i++) {
System.out.println(result[i]);
}
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
I was trying to write a simple max and min method, as I wrote it I just cant help feeling it shouldn’t be this complicated….maybe Im wrong?
My maximum code works like this, excuse my poor pseudo code:
Fill an array with 10 random numbers.
Create a max variable initialised to 0, because 0 is the lowest max.
Compare each element against the max
If the element is greater then max, replace the value of max with the element in question
I don’t like the fact I have to initialise max to 0, I feel there might be a better way then this?
My min code works similar except I:
Compare my min is lower then the array element.
If the element is lower replace min.
What I really don’t like about this is I have to initialise my min to the maximum random number, in this case 50.
My questions are:
Is there a better way to do this?
Is there a more efficient way to write this code?
import java.util.Random;
public class Main {
public static void main(String[] args) {
//Declare min and max
int max=0;
int min;
//Array of 10 spaces
int[] ar=new int[10];
//fill an array with random numbers between 0 and 50
for(int i=0;i<10;i++)
{
ar[i]=new Random().nextInt(50);
}
//Test max algorithm
//loop trough elements in array
for(int i=0;i<10;i++)
{
//max is set to 0, there should always be a maximum of 0
//If there isnt 0 will be the maximum
//If element is greater then max
//replace max with that element
if(ar[i]>max)
{
max=ar[i];
}
}
System.out.println("The max is "+ max);
//Test min
//Initialising min to maximum Random number possible?
min=50;
for(int i=0;i<10;i++)
{
if(ar[i]<min){
min=ar[i];
}
}
System.out.println("The min is "+min);
}
}
You can always grab the first element of the array (i.e. numbers[0]) as the initial value and start the loop from the second element.
int[] numbers = new int[10];
int max, min;
...
min = max = numbers[0];
for(int i = 1; i < numbers.length; ++i) {
min = Math.min(min, numbers[i]);
max = Math.max(max, numbers[i]);
}
Ok, while others were already posting answers, I have taken the time to edit your code into something I think would be more usable.
Make static methods. Those can be reused.
Use an ellipsis (...) because you then can either call the methods on array arguments like in your code, but also with a variable number of arguments as min(5,3,8,4,1).
Initialize with the smallest/biggest possible number the data type provides
To check that your code works, you have to print out the items in the array first, since when you don't know what's in it, there's no way to tell the result is correct.
Base your code on the existing methods in the standard library because these are known to be thoroughly tested and work efficiently (I know, min/max looks like a too trivial example).
I wouldn't bother too much about performance unless you really can show there is a performance problem in your code. Priority should be more like 1st correctness, 2nd readability/maintainability, 3rd performance.
Most of this has been already mentioned by others, but anyway, here's the code:
import java.util.Random;
public class MinMax {
public static int min(int... args) {
int m = Integer.MAX_VALUE;
for (int a : args) {
m = Math.min(m, a);
}
return m;
}
public static int max(int... args) {
int m = Integer.MIN_VALUE;
for (int a : args) {
m = Math.max(m, a);
}
return m;
}
public static void main(String[] args) {
// fill an array with random numbers between 0 and 50
int[] ar = new int[10];
for (int i = 0; i < 10; i++)
{
ar[i] = new Random().nextInt(50);
System.out.println(ar[i]);
}
int maxValue = max(ar);
int minValue = min(ar);
System.out.println("The max is " + maxValue);
System.out.println("The min is " + minValue);
}
}
Few tips:
Initialize min with first element and start from the second:
int min = ar[0];
for(int i=1;i<10;i++)
...or start from:
int min = Integer.MAX_VALUE;
this approach is better if you expect your array can be empty.
Use Math.min to avoid explicit condition (some may say it's slower though):
for(int i=0;i<10;i++)
{
min = Math.min(min, ar[i]);
}
Initialize max to 0 & min to 50 won't work when the numbers change. A more appropriate way is:
1. initialize them to the first element of the array.
2. Use length instead of a constant.
max = ar[0];
for(i=0;i<ar.length; i++)
{
if(ar[i]>max)
{
max=ar[i];
}
}
Same for min:
min = ar[0];
for(i=0;i<ar.length; i++)
{
if(ar[i]<min)
{
min=ar[i];
}
}
public static void main(String[] args) {
int[] myArray = {9, 7,9, -40, -10, 40};
//int[] myArray = {};
//int[] myArray = {4};
System.out.println("Difference between max and min = "
+ findDifference(myArray));
}
// Find difference between Max and Min values for a given array
public static int findDifference(int[] arr) {
if (arr.length == 0) {
// Log
System.out.println("Input Array is empty");
return Integer.MIN_VALUE;
}
int min = arr[0];
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] < min)
min = arr[i];
else if (arr[i] > max)
max = arr[i];
// Just to check if logic works fine
System.out.println("Min=" + min + " Max=" + max);
}
return max - min;
}
import java.io.*;
public class MultiDimensionalArrayIO {
public static void main(String[] args)throws IOException {
BufferedReader c= new BufferedReader (new InputStreamReader (System.in) );
System.out.print ( "Enter Number Column : " );
int column = Integer.parseInt(c.readLine());
System.out.print ( "Enter Number Row : " );
int row = Integer.parseInt(c.readLine());
int array [][] = new int [column][row];
int max = array [0][0];
int min = array [0][0];
int sum= 0;
for ( int i=0 ; i < array.length; i++){
for (int j=0 ; j<array[i].length; j++){
System.out.print("Enter Array Values ["+i+"]["+j+"]: " );
array[i][j]= Integer.parseInt (c.readLine());
min = Math.min(min , array[i][j]);
max = Math.max(max , array[i][j]);
sum += array[i][j];
}
}
System.out.println("The Min Number :"+ min);
System.out.println("The Max Number :"+ max+ " total is "+ sum);
}
}
Depending on whether you'd want the max and min-functions in the same method you also have to consider the return type.
So far most suggestions have kept the two separate, meaning it's fine to return an int. However, if you put the max and min-functions into a findLargestDifference-method you'd have to return a long seeing as the largest difference between any given numbers in the int array can be the size of 2 ints. You'd also getting rid of having to loop over the int array twice.
Furthermore I recommend writing unit tests for corner and edge cases instead of printing in a main-method. It helps test your logic early on when implementing it and thus often makes the code cleaner.
See example code below.
public class LargestDifference {
public static long find(int[] numbers) {
if (numbers == null || numbers.length == 0) {
throw new IllegalArgumentException("Input cannot be null or empty.");
}else {
long currentMax = numbers[0];
long currentMin = numbers[0];
for (int i=0; i < numbers.length; i++) {
if (currentMin > numbers[i]) {
currentMin = numbers[i];
}else if (currentMax < numbers[i]) {
currentMax = numbers[i];
}
}
return currentMax - currentMin;
}
}
Given this array
int [] myArray = {5,-11,2,3,14,5,-14,2};
You are to find the maximum sum of the values in any downsequence in an unsorted array of integers. If the array is of length zero then maxSeqValue must return Integer.MIN_VALUE.
You should print the number, 19 because the downsequence with the maximum sum is 14,5.
Downsequence number is a series of non-increasing number.
These are the codes that i used but i guess that there are some cases which is still not accounted for.
Any ideas, thanks in advance.
public class MaxDownSequence{
public int maxSeqValue(int[] a){
int sum=Integer.MIN_VALUE;
int maxsum=Integer.MIN_VALUE;
for (int i=1;i<a.length;i++){
if(a[i]<a[i-1]){
sum = a[i] + a[i-1];
if (sum>maxsum){
maxsum=sum;
}
}
else {
sum=a[i];
if (sum>maxsum){
maxsum=sum;
}
}
}
if (a.length==0){
return Integer.MIN_VALUE;
}
else{
return maxsum;
}
}
public static void main(String args[]){
MaxDownSequence mySeq = new MaxDownSequence();
int [] myArray = {5,-11,2,3,14,5,-14,2};
System.out.println(mySeq.maxSeqValue(myArray));
}
}
Take the input {3,2,1} the answer should be 6 your program gives 5.
Your approach is correct, every time you test a number in the array you check if its less than (actually this should be <=) previous array element.
If it is you update sum as: sum = a[i] + a[i-1]; this is incorrect. sum in your program represents the running rum of the current subsequence. You should not be overwriting it.
Dynamic programming is the way to go.
http://en.wikipedia.org/wiki/Dynamic_programming
I know, maybe that doesn't help at all, but since I don't want to post a solution for your problem the best thing I can do is to give you this hint :)
you haven't considered sequences of more than two numbers. If you had [3,2,1] the result should be 6. But your code would give 5, because it only looks at the sum of the current number and the previous, whereas you should keep track of a current downsequence and add the current number to the running total of that downsequence. Once you hit a number that breaks the downsequence update maxsum if needed then reset the running total to 0.
not sure why you have the else in the loop?? If a[i] is not less than a[i-1] then it is not a downsequence, therefore surely maxsum should not be updated. If you take just the first 3 numbers in your sample array, it would return the number 2. Because the first downsequence [5,-11] would give a sum of -6 and on the next iteration it would just look at 2, which is greater than -6 and therefore maxsum is updated.
No need for:
if (a.length==0){
return Integer.MIN_VALUE;
}
if the array length is 0 then you never enter the loop and therefore never change maxsum, so it will still be equal to Integer.MIN_VALUE, so you can just return maxsum at the end regardless.
You are suppose to have a running sum i think. Meaning Sum = Sum + A[i]. Just make sure to initialize the sum to the first member of the array and you are in business.
package sree;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.NestingKind;
public class MaximumSumSequence {
private final int[] theArray;
private MaximumSumSequence(int[] theArray) {
this.theArray = theArray;
}
private void maximumSequence() {
int currentMax = 0,currentSum = 0, start = 0, end = 0, nextStart = 0;
for (int i=0; i< theArray.length; i++) {
currentSum += theArray[ i ];
if (currentMax < currentSum) {
currentMax = currentSum;
start = nextStart;
nextStart = end;
end = i;
} else if (currentSum < 0) {
currentSum = 0;
}
}
System.out.println("Max Sum :" + currentMax);
System.out.println("Start :" + start);
System.out.println("End :" + end);
}
public static void main(String[] args) {
//int[] anArray = {4, -1, 2, -2, -1, -3};
int[] anArray ={-2, 1, -3, 4, -1, 2, 1, -5, 4};
new MaximumSumSequence(anArray).maximumSequence();
}
}