Finding square pair form the given array in C# - java

`I have following array {9, 0, 2, -5, 7} and from this array i need to find the the square pairs <2, 7> and <7, 9> where first element must be less than second.
And <-5, 9> and <0, 9> are not square pairs, even though they sum to perfect squares,
because both members of a square pair have to be greater than 0.
bool ans;
int[] number = new int[]{9,0,2,-5,7};
for (int j = 0; j < number.Length; j++)
{
if (number[j]<number[j+1])
ans = IsPerfectSquares(number[j]+number[j+1]);
if(ans)
count++;
}
}
public static bool IsPerfectSquares(int input)
{ long SquareRoot = (long)Math.Sqrt(input);
return ((SquareRoot * SquareRoot) == input);
} `

C# Linq:
int[] array = {9, 0, 2, -5, 7};
int len = array.Length;
var pairs =
from i in Enumerable.Range(0, len-1)
where array[i] > 0
from j in Enumerable.Range(i+1, len-i-1)
where array[j] > 0
let sqrt = (int)Math.Sqrt(array[i] + array[j])
where array[i] + array[j] == sqrt * sqrt
select new {
A = Math.Min(array[i], array[j]),
B = Math.Max(array[i], array[j])
};
//or: select new int[] { ... };
Results:
{ A = 7, B = 9 }
{ A = 2, B = 7 }
Java: (also works in C# with slightly different syntax)
int[] array = { 9, 0, 2, -5, 7 };
List<int[]> pairs = new ArrayList<int[]>();
for (int i = 0; i < array.length - 1; ++i) {
if (array[i] <= 0) continue;
for (int j = i + 1; j < array.length; ++j) {
if (array[j] <= 0) continue;
int sqrt = (int)Math.sqrt(array[i] + array[j]);
if (array[i] + array[j] == sqrt * sqrt)
pairs.add(new int[] { array[i], array[j] });
}
}

I will let you write the code.
The algorithm is roughly this:
Iterate over the array. Remove all elements whose value is less than or equal to zero.
Create all possible pairs by using nested loop (two loops). For each pair, take the sum. Let say the sum is S. Take the square root of S. Let say the square root of R. Note that S is an integer (so, it may not exactly the square root of S). Check whether S is a perfect square by checking whether R*R = S.

Related

How can i find and print the smallest number in array which occurs exactly K times in an array, where K is an user input?

I've earlier used nested approach which is giving me TLE.
-we can not use nested approach for this.
- time limit is 1 sec and 5000kb memory. Here is my nested approach
for (int i = 0; i < n; i++) {
if (arr[i] > 0) {
int count = 1;
for (int j = i + 1; j < n; j++)
if (arr[i] == arr[j])
count += 1;
if (count == k)
res = Math.min(res, arr[i]);
}
}
You can try using a dictionary that keeps track of the numbers as keys, and the number of times it appears as the value. This way you will only have to go through the array once.
Then, at the end you check which keys have a value of K, and choose the smallest of those.
Firstly you should get the max element and make count array of length max+1 elements i.e how much time each elements occurring eg:-
arr=[2,5,1,2,3,6,3] and k=2.
Now count each element, n is length of array, c is array counting element
int c[]=new int[max+1];
for(int i=0;i<=max; i++)
{
c[a[i]]+=1;
}
Arrays.sort(a);
//1 2 2 3 3 5 6
for(int i=0;i<n;i++)
{
if(c[a[i]]==k)
{
System.out.print(a[i]);
break;
}
}
This will give you desired output with time complexity O(nLogn)
How about just sorting the array and then walking through it to return the first value that occurs k times?
// return the smallest value that occurs k times, or null if none found
static Integer smallestK(int[] a, int k)
{
Arrays.sort(a);
for(int i=1, j=0; i<=a.length; i++)
{
if(i == a.length || a[i] != a[j])
{
if(i - j == k)
return a[j];
j = i;
}
}
return null;
}
Test:
int[] a = {6, 5, 3, 1, 4, 2, 5, 2, 2};
System.out.println(Arrays.toString(a));
for(int k=1; k<=4; k++)
{
Integer val = smallestK(a.clone(), k);
if(val != null)
System.out.format("k:%d, Result: %d%n", k, val);
else
System.out.format("k:%d, Not Found", k);
}
Output:
[6, 5, 3, 1, 4, 2, 5, 2, 2]
k:1, Result: 1
k:2, Result: 5
k:3, Result: 2
k:4, Not Found
You can try below approach as well. it has O(nlogn) complexity.
int[] arr1 = {10,2,15,20,25,4,25};//array
int k = 2;//minimum occurences
Arrays.sort(arr1);
HashMap<Integer,Integer> value = new HashMap<Integer, Integer>();
for(int i:arr1) {
value.put(i, value.getOrDefault(i, 0)+1);
}
for(int i:arr1) {
if(value.get(i)==k) {
System.out.println(i);
break;
}
}

Java sorting array positive ascending to negative ascending

I can't solve the problem , where I need output from array A like {1,2,3,4,-1,-2,-3,-4}
from random numbers in array, then write it to another array B. So far my experimental code doesn't work as I'd
public static void main(String[] args) {
int a[] = {5,4,3,2,1,-3,-2,-30};
int length = a.length - 1;
for (int i = 0 ; i < length ; i++) {
for (int j = 0 ; j < length-i ; j++) {
if (a[j] < a[j+1]) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
}
}
}
for (int x : a) {
System.out.print(x+" ");
}
}
Output is 5 4 3 2 1 -2 -3 -30 , but I need 1,2,3,4,5,-2,-3,-30
Update:
public static void main(String[] args) {
int a[] = {5,4,3,2,1,-3,-2,-30,-1,-15,8};
int length = a.length - 1;
for (int i = 0 ; i < length ; i++) {
for (int j = 0 ; j < length-i ; j++) {
if (a[j] < a[j+1]) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
} else {
if (a[j] > a[j+1] && a[j+1] > 0) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
}
}
}
}
for (int x : a) {
System.out.print(x+" ");
}
}
I got closer to my target but 8 1 2 3 4 5 -1 -2 -3 -15 -30 , that number 8 ruins it all
Add an if-else to differentiate the positive and negative case.
if (a[j] < 0) {
if (a[j] < a[j+1]) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
}
} else {
if (a[j] > a[j+1] && a[j+1] > 0) {
int swap = a[j];
a[j] = a[j+1];
a[j+1] = swap;
}
}
If I understand you correctly you want to sort after two things. Positive numbers from low to high and negative numbers from high to low.
You could first sort from high to low and in a second run over the array skip all positives and then sort from high to low.
Does this help?
I could write some code, but I believe that's something you want to learn right now :)
Algo:
Traverse the Array and Store positives in one and Negatives in another. O(i)
Sort the positives array in ascending order. O(mLog(m))
Sort the negatives indescending order. O(nLog(n))
Create a final array of the size of the input.
Add all the positive array sorted values. Then add the negative array sorted values. O(i)
Total : O(i) + O(mLog(m)) + O(nLog(n)) + O(i) = O(mLog(m)) if m > n
I have used library functions here. But if you want you can the write the functions using the same idea.
public class PostivieAsendingNegativeDesending implements Comparator<Integer> {
public static void main(String args[]) {
int fullList[] = {5, 4, 3, 2, 1, -3, -2, -30};
ArrayList<Integer> subList = new ArrayList<>();
ArrayList<Integer> subList2 = new ArrayList<>();
for (int i = 0; i < fullList.length; i++) {
if (fullList[i] < 0) {
subList2.add((fullList[i]));
} else {
subList.add(fullList[i]);
}
}
Collections.sort(subList);
Collections.sort(subList2, new PostivieAsendingNegativeDesending());
subList.addAll(subList2);
for (int i = 0; i < subList.size(); i++) {
System.out.print(subList.get(i) + " ");
}
System.out.println("");
}
#Override
public int compare(Integer n1, Integer n2) {
return n2 - n1;
}
}
This will do the trick which uses only basic loops
public static void main(String[] args) {
int a[] = { 5, 4, 3, 2, 1, -3, -2, -30 };
int length = a.length - 1;
int pos = 0, neg = 0;
// find total count of positive and negative numbers
for (int i = 0; i <= length; i++) {
if (a[i] < 0)
neg++;
else
pos++;
}
// initialize the arrays based on 'pos' and 'neg'
int posArr[] = new int[pos];
int negArr[] = new int[neg];
// store pos and neg values in the arrays
int countPos = 0, countNeg = 0;
for (int i = 0; i <= length; i++) {
if (a[i] < 0) {
negArr[countNeg] = a[i];
countNeg++;
} else {
posArr[countPos] = a[i];
countPos++;
}
}
// sort positive numbers
for (int i = 0; i < posArr.length - 1; i++) {
for (int j = 0; j < posArr.length - 1 - i; j++) {
if (posArr[j] > posArr[j + 1]) {
int swap = posArr[j];
posArr[j] = posArr[j + 1];
posArr[j + 1] = swap;
}
}
}
// sort negative numbers
for (int i = 0; i < negArr.length - 1; i++) {
for (int j = 0; j < negArr.length - 1 - i; j++) {
if (negArr[j] < negArr[j + 1]) {
int swap = negArr[j];
negArr[j] = negArr[j + 1];
negArr[j + 1] = swap;
}
}
}
// 1. print out posArr[] and then negArr[]
// or
// 2. merge them into another array and print
}
Logic is explained below :
Find total count of positive and negative numbers.
Create and store the positive and negative values in the respective arrays.
Sort positive array in ascending order.
Sort negative array in descending order.
Print out positive array followed by the negative array OR merge them into another and print.
I suggest another approach. You should try to formulate the rules to which the exact comparison must adhere.
Your requirement seem to have the following rules:
Positive numbers always come before negative numbers.
Positive numbers are ordered in ascending order.
Negative numbers are ordered in descending order. Yes, I said descending. Since higher numbers come before lower numbers, i.e. −2 is greater than −7.
Warning: you are using a nested for loop, which means that the process time will grow exponentially if the array becomes larger. The good news is: you don't need to nest a for loop into another for loop. I suggest writing a Comparator instead:
// The contract of Comparator's only method 'compare(i, j)' is that you
// return a negative value if i < j, a positive (nonzero) value if i > j and
// 0 if they are equal.
final Comparator<Integer> c = (i, j) -> { // I'm using a lambda expression,
// see footnote
// If i is positive and j is negative, then i must come first
if (i >= 0 && j < 0) {
return -1;
}
// If i is negative and j is positive, then j must come first
else if (i < 0 && j >= 0) {
return 1;
}
// Else, we can just subtract i from j or j from i, depending of whether
// i is negative or positive
else {
return (i < 0 ? j - i : i - j);
}
}
Your code could look like this:
int[] a = { 5, 4, 3, 2, 1, -3, -2, -30 };
int[] yourSortedIntArray = Arrays.stream(a)
.boxed()
.sorted(c) // Your Comparator, could also added inline, like
// .sorted((i, j) -> { ... })
.mapToInt(i -> i)
.toArray();
Lambda expressions are a new concept from Java 8. The Java Tutorials provide some valuable information.

Developing two different algorithms for finding a certain element in an array

I am currently practicing algorithm development with Java and have recently really got stuck on a particular problem. I have been challenged to develop two different algorithm.
My task is to solve the selection problem. the selection problem determines the kth largest number in a group of N numbers.
I have successfully implemented the first algorithm. I read the N numbers into an array, sort the array in decreasing order by some simple algorithm, and then return the element in position k.
Note: k = N / 2
Here is the working code
public int selectionAlgorithmOne() {
int[] intArray = new int[]{1, 7, 9, 8, 2, 3, 5, 4, 6, 10};
//I sort the array of size N in decreasing order
bubbleSortDecreasingOrder(intArray);
//{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}
//I obtain the value of k
int k = intArray.length / 2;
//I print the result
System.out.println(intArray[k]);
}
The value that is printed in "5" which is correct! However, the second algorithm is a bit trickier.
Read the first k elements into an array and sort them in decreasing order. Next, each remaining element is read one by one. As a new element arrives, it is ignored if it is smaller than the kth element in the array. Otherwise, it is placed in its correct spot in the array, bumping one element out of the array. When the algorithm ends, the element in the kth position is returned as the answer.
Unfortunately my second algorithm does not work. It returns the value "3" which is wrong. It should be returning the same value of "5" as the first algorithm but in a more efficient.
I have been stuck for a few days now and I am really struggling to find the solution. Hopefully I have given the problem enough context, let me know if I can provide any more information. Thanks in advance.
Here is the non-working code
public int selectionAlgorithmTwo() {
int[] intArray = new int[]{1, 7, 9, 8, 2, 3, 5, 4, 6, 10};
int arrayLength = intArray.length;
int k = arrayLength / 2;
int[] firstHalf = new int[k];
//I read the first half of the elements into an array
for (int i = 0; i < k; i++) {
firstHalf[i] = intArray[i];
}
//I then sort the first half of the elements in decreasing order
bubbleSort(firstHalf);
for(int i = k; i < arrayLength; i++) {
int val = intArray[i];
//If the new element to insert is >= the kth largest
if (val > firstHalf[k - 1]) {
int pos = 0;
for(; pos < k; pos++) {
if(val > firstHalf[pos]) {
break; //I break once I have the correct position located
}
//I make the swap
for (int j = k - 1; j > pos; j--)
firstHalf[j] = firstHalf[j - 1];
firstHalf[pos] = val;
}
}
}
return firstHalf[k - 1];
}
First of all, "the element in position k" isn't the kth element, it's the k+1 th element. Indeed 5 is the sixth element of the sorted array.
So, if you want to return the element in position k, you need an array of k+1 element.
Therefore I added the firstHalfLen variable.
If you use an array of k element, you'll never get 5 as answer.
In the block if (val > firstHalf[k]), in order to find the correct index, I preferred a while loop
while ((pos < firstHalfLen) && (val <= firstHalf[pos])) {
pos++;
}
Then the swap:
for (int j = k; j > pos; j--) {
firstHalf[j] = firstHalf[j - 1];
}
Code:
int[] intArray = new int[] { 1, 7, 9, 8, 2, 3, 5, 4, 6, 10 };
int arrayLength = intArray.length;
int k = arrayLength / 2;
int firstHalfLen = k + 1;
int[] firstHalf = new int[firstHalfLen];
// I read the first half of the elements into an array
for (int i = 0; i < firstHalfLen; i++) {
firstHalf[i] = intArray[i];
}
//I then sort the first half of the elements in decreasing order
bubbleSort(firstHalf);
for (int i = firstHalfLen; i < arrayLength; i++) {
int val = intArray[i];
// If the new element to insert is >= the kth largest
if (val > firstHalf[k]) {
int pos = 0;
// find index
while ((pos < firstHalfLen) && (val <= firstHalf[pos])) {
pos++;
}
// Swap
for (int j = k; j > pos; j--) {
firstHalf[j] = firstHalf[j - 1];
}
firstHalf[pos] = val;
}
}
return firstHalf[k];
You are comparing values from the unsorted part to values of the sorted part, starting low, i.e. at small values. The probability that the value is larger than the first sorted value is quite high. More interesting would be a value which is smaller. According to your algorithm, the smaller unsorted value should be inserted into the small sorted values, at the position where it replaces a higher value, not a smaller one.
So
if(val > firstHalf[pos])
should be
if(val < firstHalf[pos])
Try this code:
public int sortTest() {
int[] intArray = new int[]{1, 7, 9, 8, 2, 3, 5, 4, 6, 10};
int arrayLength = intArray.length;
int k = arrayLength / 2;
int[] firstHalf = new int[k];
//I read the first half of the elements into an array
for (int i = 0; i < k; i++) {
firstHalf[i] = intArray[i];
}
//I then sort the first half of the elements in decreasing order
bubbleSort(firstHalf);
for(int i = k; i < arrayLength; i++) {
int val = intArray[i];
//If the new element to insert is >= the kth largest
if (val > firstHalf[k - 1]) {
int pos = 0;
for(; pos < k; pos++) {
if(val > firstHalf[pos]) {
break; //I break once I have the correct position located
}
}
//I make the swap
for (int j = k - 1; j > pos; j--)
firstHalf[j] = firstHalf[j - 1];
firstHalf[pos] = val;
}
}
return firstHalf[k - 1];
}
The error in your code is that, after you found the correct position and break, you leave the for loop without the swap procedure.
Also note that this code return 6, not 5, because you returned the k-1 th value.

Rearrange int array so that all the negative numbers come before the positivite numbers

I am trying to write a method which takes an array of ints and then rearranges the numbers in the array so that the negative numbers come first. The array does not need to be sorted in any way. The only requirement is that the solution has to be linear and it does not use an extra array.
Input:
{1, -5, 6, -4, 8, 9, 4, -2}
Output:
{-5, -2, -4, 8, 9, 1, 4, 6}
Now as a noob in Java and programming in general I am not 100% sure on what is considered a linear solution, but my guess is that it has to be a solution that does not use a loop within a loop.
I currently have an awful solution that I know doesn't work (and I also understand why) but I can't seem to think of any other solution. This task would be easy if I were allowed to use a loop within a loop or an additional array but I am not allowed to.
My code:
public static void separateArray(int[] numbers) {
int i = 0;
int j = numbers.length-1;
while(i<j){
if(numbers[i] > 0){
int temp;
temp = numbers[j];
numbers[j] = numbers[i];
numbers[i] = temp;
System.out.println(Arrays.toString(numbers));
}
i++;
j--;
}
}
You only need to change one line to get it (mostly) working. But you need to change two lines to correctly handle zeroes in the input. I have highlighted both of these minimally necessary changes with "FIXME" comments below:
public static void separateArray(int[] numbers) {
int i = 0;
int j = numbers.length-1;
while(i<j){
if(numbers[i] > 0){ // FIXME: zero is not a "negative number"
int temp;
temp = numbers[j];
numbers[j] = numbers[i];
numbers[i] = temp;
}
i++; // FIXME: only advance left side if (numbers[i] < 0)
j--; // FIXME: only decrease right side if (numbers[j] >= 0)
}
}
Your approach with two pointers, i and j is a good start.
Think about the loop invariant that you immediately set up (vacuously):
Elements in the range 0 (inclusive) to i (exclusive) are negative;
Elements in the range j (exclusive) to numbers.length (exclusive) are non-negative.
Now, you want to be able to move i and j together until they pass each other, preserving the loop invariant:
If i < numbers.length and numbers[i] < 0, you can increase i by 1;
If j >= 0 and numbers[j] >= 0, you can decrease j by 1;
If i < numbers.length and j >= 0, then numbers[i] >= 0 and numbers[j] < 0. Swap them around.
If you keep applying this strategy until i == j + 1, then you end up with the desired situation, that:
numbers[a] < 0 for a in [0..i)
numbers[a] >= 0 for a in (j..numbers.length), also written as numbers[a] >= 0 for a in (i-1..numbers.length), also written as numbers[a] >= 0 for a in [i..numbers.length).
So, you've partitioned the array so that all negative numbers are on the left of the i-th element, and all non-negative numbers are at or to the right of the i-th element.
Hopefully, this algorithm should be easy to follow, and thus to implement.
A linear solution is a solution with a run-time complexity Big-Oh(n) also noted as O(n), in other words, you have to loop through the whole array only once. To sort in linear time you can try one of the following sorting algorithms:
Pigeonhole sort
Counting sort
Radix sort
Your code works only if all the negative numbers are located in the right half side and the positives in the left half. For example, your code swaps 6 with 9 which both are positives. So, it depends on the order of your the array elements. As scottb said, try do it by your hands first then you will notice where you did wrong. Moreover, print your array out of the while
//Move positive number left and negative number right side
public class ArrangeArray {
public static void main(String[] args) {
int[] arr = { -2, 1, -3, 4, -1, 2, 1, -5, 4 };
for (int i = 0; i < arr.length; i++) {
System.out.print(" " + arr[i]);
}
int temp = 0;
for (int i = 0; i < arr.length; i++) {
// even
if (arr[i] < 0) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] > 0) {
arr[j] = arr[i] + arr[j];
arr[i] = arr[j] - arr[i];
arr[j] = arr[j] - arr[i];
break;
}
}
}
}
System.out.println("");
for (int i = 0; i < arr.length; i++) {
System.out.print(" " + arr[i]);
}
}
}
There is simple program it will help you. In this program i have take temp array and perform number of item iteration. In that i have start fill positive value from right and negative from left.
public static void rearrangePositiveAndNegativeValues() {
int[] a = {10,-2,-5,5,-8};
int[] b = new int[a.length];
int i = 0, j = a.length -1;
for (int k = 0; k < a.length ; k++) {
if (a[k] > 0) {
b[j--] = a[k];
} else {
b[i++] = a[k];
}
}
System.out.println("Rearranged Values : ");
printArray(b);
}
package ArrayProgramming;
import java.util.ArrayList;
import java.util.Arrays;
public class RearrangingpossitiveNegative {
public static void main(String[] args) {
int[] arr= {-1,3,4,5,-6,6,8,9,-4};
ArrayList<Integer> al = new ArrayList<Integer>();
for (int i=0;i<arr.length;i++) {
if(arr[i]>0) {
al.add(arr[i]);
}
}
for (int i=arr.length-1;i>=0;i--) {
if(arr[i]<0) {
al.add(arr[i]);
}
}
System.out.println(al);
}
}
from array import *
size = int(input())
arr = (array('i' , list(map(int, input().split()))))
negarr = array('i')
posarr = array('i')
for i in arr:
if i>=0:
posarr.append(i)
else:
negarr.append(i)
print(*(negarr+posarr))
we can also do it by creating two new arrays and adding elements into them as per given condition. later joining both of them to produce final result.

Java - how to stop nested loops from checking same indices twice?

Given an array and a number N call a pair of numbers from the array a Perfect Pair if their sum is equal to N.
Find all of the perfect pairs and return the sum of their indices. Note that any element of the array can only be counted in one Perfect Pair.
Examples
pairwise([1, 4, 2, 3, 0, 5], 7) = 11
Since the Perfect Pairs are (4, 3) and (2, 5) with indices 1 + 3 + 2 + 5 = 11.
pairwise([1, 3, 2, 4], 4) = 1
Since the element at index 0 (i.e. 1) and the element at index 1 (i.e. 3) form the only Perfect Pair.
Input 1 (arr) → array.integer :
array of non-negative integers
Input 2 (N) → integer :
positive integer
Output → integer :
sum of indices and 0 if no Perfect Pair exists
My Code:
public static void main(String[] args) {
int x[] = {1,4,2,3,0,5};
System.out.println(pairwise(x, 7));
}
public static int pairwise(int[] arr, int N) {
int t=0;
for(int i=0;i<arr.length;i++){
for(int k=0;k<arr.length;k++){
if(arr[i]+arr[k] == N){
t+=i+k;
}
}
}
return t;
}
The problem is my code checks indices twice, like (0,1) and (1,0) are treated like different indices.
The simplest options is to not check these in the first place. I assume i == k is not valid so you don't want to check k < i either.
public static void main(String[] args) {
int x[] = {1, 4, 2, 3, 0, 5};
System.out.println(pairwise(x, 7));
}
public static int pairwise(int[] arr, int N) {
int t = 0;
for (int i = 0; i < arr.length - 1; i++) {
for (int k = i + 1; k < arr.length; k++) {
if (arr[i] + arr[k] == N) {
t += i + k;
arr[i] = arr[k] = Integer.MIN_VALUE; // don't use these again
continue;
}
}
}
return t;
}
prints
11
This ensures you won't go over the same numbers twice.
Note: this is an O(n^2) approach, if you have more numbers you will want an O(n) approach which means using a set or map of numbers.
// O(n)
Map<Integer, Integer> intToIndex = new HashMap<>();
for(int i = 0; i < arr.length; i++)
intToIndex.put(arr[i], i);
// O(n)
for(int i = 0; i < arr.length; i++) {
int numberToLookFor = N - arr[i];
Integer k = intToIndex.get(numberToLookFor);
if (k != null) {
assert arr[i] + arr[k] == N;
// do something with i and k
}
}
Start the second loop from i, not 0.
for(int i = 0; i < 10; i++)
{
for(int j = i; j < 10; j ++)
{
System.out.println("(" + i + "," + j + ")");
}
}
Output:
I reduced `10` to `4`.
(0,0)
(0,1)
(0,2)
(0,3)
(0,4)
(1,1)
(1,2)
(1,3)
(1,4)
(2,2)
(2,3)
(2,4)
(3,3)
(3,4)
(4,4)

Categories

Resources