K-complementary pairs using given array of integers effectively - java

I am very new to programming. I need to find the K-complementary pairs using given array of integers effectively. I have written the below code. It includes the duplication. I need to eliminate that duplication. So please help me to remove that duplication and please suggest if there is a better efficient way to do it.
public class KComplexityOfArray {
public static StringBuffer oldFunction(int arr[], int k) {
int result = 0;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
if (i != j && arr[i] + arr[j] == k) {
sb.append(arr[i] + "," + arr[j]);
result++;
}
}
}
System.out.println(result);
return sb;
}
public static void main(String[] args) {
int[] intArray1 = new int[]{4, 5, 6, 3, 1, 8, -7, -6, 7};
int[] intArray2 = new int[]{1, 2, 7, 5, 6, 3};
int[] intArray = new int[]{4, 5, 6, 3, 1, 8, -7, -6};
int k = 9;
System.out.println("No of k complementary pairs : " + oldFunction(intArray2, k));
}
}
Please anybody help me to sort this out. Thanks

This code is wrong, considering two different elements constitute a pair:
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
Instead you should do j=i+1:
for (int i = 0; i < arr.length; i++) {
for (int j = i+1; j < arr.length; j++) {
please suggest if there is a better efficient way to do it.
Your solution has TC of O(N^2). Instead you can reduce it in O(NlogN). See how:
Sort the array.
Use two index positions, i and j set to 0 and N-1 resp.
Now, if the sum of a[i] and a[j] equals k, print it. Else if sum < K, advance i by 1, else reduce j by 1.
Repeat Step 3 till (i < j)
Step 1 takes O(NlogN) and remaining steps take O(N); combining both incurs O(NLogN)

If I understand correctly your problem, you should replace
for (int j = 0; j < arr.length; j++) {
with
for (int j = i+1; j < arr.length; j++) {

Related

Keeping indexes of an elements in the array after sorting in Java

I want that sorting array without actually changing its data. So I want only keep its indexes in another array. For this I use Bubble Sort algorithm, and at every swapping step I change elements of new array which keeps indexes of actual array. That's my code, but it doesn't work correctly
int[] bSort(int[] arrivalTimes) {
int[] sequence = new int[arrivalTimes.length];
for (int i = 0; i < sequence.length; i++) {
sequence[i] = i;
}
for (int i = 0; i < arrivalTimes.length - 1; i++) {
for (int j = i + 1; j < arrivalTimes.length; j++) {
if (arrivalTimes[i] > arrivalTimes[j]) {
int temp = sequence[i];
sequence[i] = sequence[j];
sequence[j] = temp;
}
}
}
return sequence;
}
So if input array is [2, 5, 1, 0, 4]
Then sequence array should be [3, 2, 0, 4, 1] (indexes of actual array)
You're forgetting to sort the actual array also. If the arrivalTimes array isn't sorted, your condition will not act the way you expect.
int[] bSort(int[] arrivalTimes) {
int[] sequence = new int[arrivalTimes.length];
for (int i = 0; i < sequence.length; i++) {
sequence[i] = i;
}
for (int i = 0; i < arrivalTimes.length - 1; i++) {
for (int j = i + 1; j < arrivalTimes.length; j++) {
if (arrivalTimes[i] > arrivalTimes[j]) {
int temp = sequence[i];
sequence[i] = sequence[j];
sequence[j] = temp;
int temp2 = arrivalTimes[i];
arrivalTimes[i] = arrivalTimes[j];
arrivalTimes[j] = temp2;
}
}
}
return sequence;
}
This is an inefficient solution though. I suspect this is part of some algorithms assignment so I'll leave the optimisations up to you.

Swap even odd indices in a java int array

I am trying to swap numbers in int array according to even and odd indices.
So far,
I was able to work out how to target even and odd indices but,
then because of nested for loops I am not able to print all the elements in one array.
Here is my code -
public class SwapIndexes {
public static void main(String []args) {
int temp;
int[] arr = {1, 2, 3, 4, 5, 6};
for (int j = 0; j < arr.length; j += 2) {
for (int k = 1; k < arr.length; k += 2) {
temp = arr[j];
arr[j] = arr[k];
arr[k] = temp;
System.out.print(arr[k]);
}
}
}
}
This code gives 124312531 as output for arr[k] and gives 246124312 as output for arr[j]. I want the output to be
2,1,4,3,6,5
I really don't understand why you have two loops. You only need one since you need to browse the array only once. Here is the code with one loop: j will have all the odd indexes and then you switch j-1 and j.
Since no specification is given about the behavior of an array with an odd number of elements, in that case it doesn't modify the last value. If needed, you can throw an exception.
public static void main(String []args) {
int temp;
int[] arr = {1, 2, 3, 4, 5, 6};
for (int j = 1; j < arr.length; j += 2) {
temp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = temp;
}
System.out.print(Arrays.toString(arr));
}
Well, I don't know why you have use two loop because the idea was there.
Remove the second loop, set k to j + 1 and the logic is here (commented the code that you don't need.
for (int j = 0; j < arr.length; j += 2) {
//for (int k = 1; k < arr.length; k += 2) {
int k = j + 1;
temp = arr[j];
arr[j] = arr[k];
arr[k] = temp;
//System.out.print(arr[k]);
//}
}
System.out.print(Arrays.toString(arr));
Now, you need to prevent exception to occurs for uneven length.
I like to simple use a slightly different loop :
for (int j = 1; j < arr.length; j += 2) {
int k = j - 1;
...
}
System.out.print(Arrays.toString(arr));
All you have to do is check if there is at least 2 cells, which make sense if you want to reverse an array like this
if(arr.length < 2)
return;
Test 1:
{1, 2, 3, 4, 5, 6}
[2, 1, 4, 3, 6, 5]
Test 2:
{1, 2, 3, 4, 5, 6, 7}
[2, 1, 4, 3, 6, 5, 7]

Changing sorting algorithm java

starting Java coder here. I was wondering how to change my code so it would sort array by always swapping the biggest value to first. Sample output should be:
[3, 1, 2, 0] [3, 2, 1, 0].
public class Sorting {
static void biggest(int[] arr, int start, int end) {
for (start = 0; start < arr.length; start++) {
for (end = start + 1; end < arr.length; end++) {
if (arr[start] < arr[end]) {
int temp = arr[end];
arr[end] = arr[start];
arr[start] = temp;
System.out.println(Arrays.toString(arr));
}
}
}
}
public static void main(String[] args) {
int[] arr = {0, 1, 2, 3};
int temp = 0;
for (int i = 0; i < 4; ++i) {
biggest(arr, temp, 4 - 1);
for (int j = 0; j < 4; ++j) {
}
++temp;
}
}
Thanks in advance,
- Em
If you just want the sort to be successful, I suggest taking advantage of Java's built in sort method then reversing the list as suggested here:
Arrays.sort(arr);
ArrayUtils.reverse(arr);
But it sounds like the spirit of your question is to modify your code for this purpose. Here's the solution I came up with:
import java.util.Arrays;
public class Sorting {
static void biggest(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println(Arrays.toString(arr));
int max, maxAt = i;
for (int j = i; j < arr.length; j++) {
maxAt = arr[j] > arr[maxAt] ? j : maxAt;
}
max = arr[maxAt];
if (arr[i] < max) {
arr[maxAt] = arr[i];
arr[i] = max;
}
}
}
public static void main(String[] args) {
int[] arr = {0, 1, 2, 3};
biggest(arr);
System.out.println(Arrays.toString(arr));
}
}
First off, you had a lot of extra code that you didn't need. It's a bad idea to have a loop in your main. That should be handled by the helper function. You also had a lot of redundant declarations (like start and end). You were on the right track with your helper function, but because of your main loop your time complexity was 0(n²). Eliminating that allows mine to be O(logn). Complexity aside, the key difference in terms of logic is here in your internal loop:
for (end = start + 1; end < arr.length; end++) {
if (arr[start] < arr[end]) {
int temp = arr[end];
arr[end] = arr[start];
arr[start] = temp;
In this loop you're switching the array entry with the first one you find that's bigger. This will result in unwanted early switches (like 1 & 2). Here is my solution:
for (int j = i; j < arr.length; j++) {
maxAt = arr[j] > arr[maxAt] ? j : maxAt;
}
max = arr[maxAt];
if (arr[i] < max) {
arr[maxAt] = arr[i];
arr[i] = max;
}
The key difference is that I search for the maximum value entry following the one we're swapping. That way as we proceed through the array we will always bring forward the next biggest.
Best of luck learning Java I hope this helps!

Why does my sorting algorithm fails after the 3rd iteration of the for loop?

/*
This is the prompt:
starts with an unsorted array a
output: sorted array a.
Find the smallest element in the array a[1: n], call it a[j].
Swap it with a[0], if it is smaller than a[0].
Repeat this process with index 1, 2, ... until the who array is sorted.
*/
public class assing2 {
public static void main(String args[])
{
//array of ints
int[] A = new int[] {33, 20, 8, 11, 5};
int min_id = 0;
int temp_i = 0;
//int temp_max = 0;
for (int i = 0; i < A.length; i++)
{
min_id = i;
temp_i = A[i];
for (int j = 1; j < A.length; j++)
{
if (A[min_id] > A[j])
{
min_id = j;
}
}
A[i] = A[min_id];
A[min_id] = temp_i;
}
System.out.println("Sorted array");
for ( int i = 0; i < A.length; i++)
{
System.out.println(A[i]);
}
}
}
This is the output
Sorted array
5
20
11
33
8
When I run it in the debugger i can see that the first 2 iterations of the first for loop looks like its working but after that it unsorted what was sorted.
Whats is wrong with my logic?
for (int j = 1; j < A.length; j++)
is wrong. You should check only the elements after i, since the elements before i are sorted by the previous iterations. So it should be
for(int j = i+1; j < A.length; j++)
Also in the first loop, you dont need to do anything about the last element. You can change the stop condition to i<A.length-1

Trouble with splitting an array into chunks

I have an array:
private static int[] array = {5, 2, 1, 6, 3, 7, 8, 4};
I'm trying to split it into a two-dimensional array with x amount of chunks, where all of the chunks have an equal length (in my case, 2), then assign each value of the original array to a corresponding index within the array. It would then increment the index of the chunk number and reset the index iterating through the individual arrays hit the length of one.
Problem is, the code I wrote to perform all that isn't outputting anything:
public class Debug
{
private static int[] array = {5, 2, 1, 6, 3, 7, 8, 4};
private static void chunkArray(int chunkSize)
{
int chunkNumIndex = 0;
int chunkIndex = 0;
int numOfChunks = (int)Math.ceil((double)array.length / chunkSize);
int[][] twoDimensionalArray = new int[numOfChunks][chunkSize];
for (int i = 0; i < array.length; i++)
{
twoDimensionalArray[chunkNumIndex][chunkIndex] = array[i];
chunkIndex++;
while(chunkNumIndex < numOfChunks)
{
if (chunkIndex == chunkSize)
{
chunkNumIndex++;
chunkIndex = 0;
}
}
}
for(int i = 0; i < chunkNumIndex; i++)
{
for(int j = 0; j < chunkIndex; j++)
{
System.out.printf("%5d ", twoDimensionalArray[i][j]);
}
System.out.println();
}
}
public static void main(String args[])
{
chunkArray(2);
}
}
Could anyone be of assistance in debugging my program?
The problem is that you have an unnecessary while(chunkNumIndex < numOfChunks) which makes no sense. The if statement is sufficient to iterate your variables correctly:
for (int i = 0; i < array.length; i++) {
twoDimensionalArray[chunkNumIndex][chunkIndex] = array[i];
chunkIndex++;
if (chunkIndex == chunkSize) {
chunkNumIndex++;
chunkIndex = 0;
}
}
Also, remember that the values of chunkNumIndex and chunkIndex are dynamic, so for the last for loops, use twoDimensionalArray.length and twoDimensionalArray[0].length instead:
for(int i = 0; i < twoDimensionalArray.length; i++) {
for(int j = 0; j < twoDimensionalArray[0].length; j++) {
System.out.printf("%5d ", twoDimensionalArray[i][j]);
}
}
You're making this unnecessarily hard, there is no need to keep counters for chunkIndex and chunkNumIndex, we can just div and mod i.
int numOfChunks = (array.length / chunkSize) + (array.length % chunkSize == 0 ? 0 : 1);
int[][] twoDimensionalArray = new int[numOfChunks][chunkSize];
for (int i = 0; i < array.length; i++) {
twoDimensionalArray[i / chunkSize][i % chunkSize] = array[i];
}
Something like this should already do the job.

Categories

Resources