I want to know how to search a number, for instance T, exists if we addition the elements of a list.
For exemple, if I have a list L=[1,5,-2,6] and T= 3, T exists.
The list hits 20 to 30 elements, any ideas ?
Well, if someone wants to know one day here's what I found :
final nt TAB_SIZE = 30;
int[] tab = new int[TAB_SIZE];
for(int i = 0; i < TAB_SIZE; i++){
tab[i] = i;
}
int T = -1;
int n = tab.length;
if (isSubsetSum(tab, n, T))
System.out.println("Found");
else
System.out.println("Not found");
public boolean isSubsetSum(int tab[], int n, int T){
if (T == 0)
return true;
if (n == 0) //So T !=0
return false;
//If the last element is higher, we ignore it
if (tab[n-1] > T)
return isSubsetSum(tab, n-1, T);
//Otherwise, looking if the sum can be obtain bith adding ou excluding the last element
return isSubsetSum(tab, n-1, T) || isSubsetSum(tab, n-1, T-tab[n-1]);
}
This algorithm is really fast but will only works with positive values
Related
I was wondering if it is possible to find the closest lower element in a non-empty sorted array for an element that may be there or may not be there. Elements can be repeated also any number of times. All elements of the array +ve.
For example, if we had the values [2,5,6,7,7,8,9] and we are looking for the element closest lower to 6, it should return 5, because 5 is the biggest number in the array, that is smaller than 6.
Similarly, if we're looking for the element closest lower to 9, it should return 8, because 8 is the biggest number in the array, that is smaller than 9.
And if the closest lower element is not found, return -1 like if we're looking for the element closest lower to 1, it should return -1, because there is no such element which can be lower than 1. Here -1 represents that there's no such value is present in the array which is closest lower to the element
I have tried this below code. Is it all right? If I'm missing something, please help me. Java code will be more helpful.
static int find(int[] a, int target)
{
int n = a.length;
if(target <= a[0])
return -1;
if(target > a[n-1])
return a[n-1];
int i=0,j=n,mid=0;
while(i<j)
{
mid = (i+j)/2;
if(target <= a[mid])
{
if( mid >0 & target> a[mid-1] )
{
return a[mid-1];
}
j= mid;
}
else
{
if( mid<(n-1) & target > a[mid+1] )
{
return a[mid+1];
}
i= mid+1;
}
}
return mid;
}
Using streams:
import java.util.stream.IntStream;
public class FindNearestLowestValue {
public final static void main(String[] args) {
int[] array = {2,5,6,7,7,8,9};
int searchVal = 6;
// reverse the order so the first element of the filtered stream is the result
System.out.println(
IntStream.range(0, array.length)
.map(i -> array[array.length - 1 - i])
.filter(n -> n < searchVal)
.findFirst().orElse(-1)
);
}
}
There exists a standard binarySearch function.
static int find(int[] a, int target) {
int position = Arrays.binarySearch(a, target);
if (position >= 0) {
System.out.println("Found at index " + position);
} else {
int insertIndex = ~position;
System.out.println("Insert position at index " + insertIndex);
position = insertIndex;
}
return position;
}
When not found it delives the ones-complement of the insert position, as shown above. This means when the result is negative, the item is not found.
It does more or less what you did, but on not finding, it cleverly return a negative: ~ insert position (or -insert position - 1).
/**
* Search the next smaller array element.
* #param a the array sorted in ascending order.
* #param target the value to keep below.
* #return the greatest smaller element, or -1.
*/
static int findNextSmaller(int[] a, int target) {
int i= Arrays.binarySearch(a, target);
if (i >= 0) {
--i;
while (i>= 0 && a[i] == target) {
--i;
}
} else {
i = ~i;
--i;
}
return i == -1 ? -1 : a[i];
}
Or, as int is discrete:
static int findNextSmaller(int[] a, int target) {
int i= Arrays.binarySearch(a, target - 1);
if (i >= 0) {
return target - 1;
}
i = ~i;
--i;
return i == -1 ? -1 : a[i];
}
I'm trying to write a method that takes a 2D array(arranged so that the elements in every row are in increasing order from left to right, and the elements in every column are in increasing order from top to bottom) and an int, and sees if the int is in the 2D array. I wanted to use nested loops, but that would make it go in O(N^2) time. I'm therefore trying to make conditionals that make it so it tests if the int is smaller than the first in one of the sub arrays and bigger than the last, and if so, goes onto the next subarray. Here's what I have:
static boolean has(int number, int[][] a) {
int q = 0;
boolean c = false;
for (int i = 0; i < a[q].length-1; i++){
if ((number < a[i][q]) || (number > a[a[j].length-1][i])){
q++;
}
else if (number == a[i][q]){
c = true;
break;
}
else c = false;
}
return c;
}
could use some help. This method compiles but gives me outOfBounds Thanks!
This solution runs in O(n+m):
static boolean has(int number, int[][] a) {
int row = 0;
int col = a[0].length - 1;
while (row < a.length && col >= 0) {
int n = a[row][col];
if (n < number) {
row++;
} else if (n > number) {
col--;
} else {
return true;
}
}
return false;
}
You can solve this in O(log(n) + log(m)) first find the row that contain the integer you're looking for using binary search (since columns are sorted), then find the exact position of the integer in that row, by performing another binary search (since rows are sorted).
I am trying to create a binary search function and I keep getting stuck in a loop. I am confined to using such magnets. The program already gives me elements to search for. The code below creates an infinite loop.
public class Student < T extends Comparable <? super T >> {
public int binarySearchIter(T[] data, T key) {
int first = 0;
int last = data.length - 1;
int mid, result;
mid = (first + last) / 2;
result = key.compareTo(data[mid]);
while (first <= last) {
if (result == -1) {
return -1;
} else if (result > 0) {
first = mid + 1;
} else {
last = mid - 1;
}
}
return mid;
}
The contract of the compareTo method is to return a positive integer, 0 or a negative integer depending on whether the number is greater, equal or less than the given number. Those numbers might or might not be -1, so you must not rely on that.
Therefore, you should change your while loop like this:
If the result is negative, the key is before the middle element so we update last to before the middle index.
If the result is positive, the key is after the middle element so we update first to after the middle index.
If the result is zero, we just found the correct index.
Also, you are not updating the middle element once you have updated the first and last variable so you should move that code inside the while loop.
public static <T extends Comparable <T>> int binarySearchIter(T[] data, T key) {
int first = 0;
int last = data.length - 1;
int mid, result;
while (first <= last) {
mid = (first + last) / 2;
result = key.compareTo(data[mid]);
if (result < 0) {
last = mid - 1;
} else if (result > 0) {
first = mid + 1;
} else {
return mid;
}
}
return -1;
}
If this is supposed to be a binary search, while loop should start just above mid = (first + last) / 2;
Plus the note from Tunaki.
we got a matrix size of NxN which is represented by a multidimentional array, the matrix contains integer numbers, we assume that N=2^K.
We can also say that the matrix is ordered by cutting the matrix to 4 quarters (image below), every element in the first quarter is smaller or equal to the element in the second quarter, every element in the second quarter is smaller or equal to the third quarter, and every element in the third quarter is smaller or equal to every element in the forth quarter. (and so on recursivly)
like this:
1 2
3 4
Example of sorted matrix:
We need to write a function that returns true if the num exist in the matrix.
and to make it as most efficient as possible.
I've wrote the following function:
public static boolean isExist(int[][] mat, int num)
{
int start_rows = 0;
int start_columns = 0;
// If more then 4 elements
// Loop log(base 4)n
for (int elements_size = mat.length * mat[0].length, table_size, quarter_size,
quarter1, quarter2, quarter3, quarter4;
(elements_size > 4);
elements_size /= 4)
{
table_size = (int)(Math.sqrt(elements_size));
quarter1 = mat[start_rows+(table_size/2)-1][start_columns+(table_size/2)-1];
quarter2 = mat[start_rows+(table_size/2)-1][start_columns+table_size-1];
quarter3 = mat[start_rows+table_size-1][start_columns+(table_size/2)-1];
quarter4 = mat[start_rows+table_size-1][start_columns+table_size-1];
if (num == quarter1 || num == quarter2 || num == quarter3 || num == quarter4) {
return true;
}
// Decrease elements_size
quarter_size = (int)Math.sqrt(elements_size/4);
if (quarter1 > num) {
// Dont do anything
} else if (quarter2 > num) {
start_columns += quarter_size; // Increase columns
} else if (quarter3 > num) {
start_rows += quarter_size; // Increase rows
} else if (quarter4 > num) {
start_rows += quarter_size; // Increase rows
start_columns += quarter_size; // Increase columns
} else {
return false; // bigger then quarter, fail.
}
}
return (mat[start_rows][start_columns] == num || mat[start_rows+1][start_columns] == num ||
mat[start_rows][start_columns+1] == num || mat[start_rows+1][start_columns+1] == num);
}
Is that the most efficient way to do so?
Also its time complexity is O(logn). (am I correct?)
well, that is a good approach!
if i understood you right, you want to find out if the array includes a specific int-value;
well, i would use the following methode (but you have to match this to a int [][] array):
HashSet<Integer> test= new HashSet<Integer>(Arrays.asList(intArray));
test.contains(intValue)
this approach is pretty fastest because the hashcode-mechanism has the complexity O(1) but i think through the asList()- it leads to arraylist complexity O(n)... not sure about this!!
It can be done in time complexity O(n). I am not sure if the post is still active. But below is my solution to do it in O(n).
public class NumberInMatrix {
public static void main(String args[]){
int matrix[][] = {{-4,-2,5,9},
{2,5,12,13},
{13,20,25,25},
{22,24,49,57},};
System.out.println(isExist(matrix, 1));
}
private static String isExist(int[][] matrix, int numberToBeSearched) {
int rowCounter = 0, colCounter = matrix[0].length - 1;
while(rowCounter < matrix.length && colCounter >= 0){
if(numberToBeSearched == matrix[rowCounter][colCounter]){
return "Number exist";
}else{
if(numberToBeSearched > matrix[rowCounter][colCounter]){
rowCounter++;
}else{
colCounter--;
}
}
}
return "Number does not exist";
}
}
I have array with constant size (size = 20 in real life), duplicates are allowed For example:
1 2 2 3 3 4 5 6 7 8 9
Now exactly one element updates:
1 5 2 3 3 4 5 6 7 8 9
I need to resort this array. Should I just use bubblesort?
update I don't know how to call what I wrote. But i suppose it is not possible to sort faster. comments are welcome!
// array is already almost sorted and INCREASING, element at pos need to be inserted to the right place
private void SortQuotes(List<Quote> quoteList, int pos)
{
var quoteToMove = quoteList[pos];
if (pos == 0 || quoteList[pos - 1].Price < quoteToMove.Price)
{
MoveElementsDown(quoteList, pos);
} else if (pos == quoteList.Count - 1 || quoteList[pos + 1].Price > quoteToMove.Price)
{
MoveElementsUp(quoteList, pos);
}
}
private void MoveElementsDown(List<Quote> quoteList, int pos)
{
var quoteToInsert = quoteList[pos];
var price = quoteToInsert.Price;
for (int i = pos - 1; i >= 0; i--)
{
var nextQuote = quoteList[i];
if (nextQuote.Price > price)
{
quoteList[i + 1] = quoteList[i];
if (i == 0) // last element
{
quoteList[i] = quoteToInsert;
}
}
else
{
quoteList[i + 1] = quoteToInsert;
break;
}
}
}
private void MoveElementsUp(List<Quote> quoteList, int pos)
{
var quoteToInsert = quoteList[pos];
var price = quoteToInsert.Price;
for (int i = pos + 1; i < quoteList.Count; i++)
{
var nextQuote = quoteList[i];
if (nextQuote.Price < price)
{
quoteList[i - 1] = quoteList[i];
if (i == quoteList.Count - 1) // last element
{
quoteList[i] = quoteToInsert;
}
}
else
{
quoteList[i - 1] = quoteToInsert;
break;
}
}
}
updated i do know which element is odd, i.e. it's position is known!
This solution shifts each element by one until the right position for the odd element is found. As it has been overwritten already in the first step, it is saved in a temporary variable 'h' and then written to the final position. It requires the minimum of comparisions and shift operations:
static void MoveOddElementToRightPosition(int[] a, int oddPosition)
{
int h = a[oddPosition];
int i;
if (h > a[oddPosition + 1])
for (i = oddPosition; i < a.Count()-1 && a[i+1] <= h; i++)
a[i] = a[i+1];
else
for (i = oddPosition; i > 0 && a[i-1] >= h; i--)
a[i] = a[i - 1];
a[i] = h;
}
Bubblesort will use n^2 time if the last element needs to get to the front. Use insertion sort.
As the array is small, insertion sort takes roughly ~O(n) time for small arrays and if you are just updating 1 value, insertion sort should fulfil your purpose in the best possible way.
It can be done in O(n). If you don't know the element then search for the element in O(n) and then You just need to compare and swap for each element and that would take O(n). So total 2n which means O(n).If you know the element which has been modified then compare and swap for each element.
If you're interested in replacing an element quickly, then you can also use a structure where deletion and insertion is fast, like for example a TreeSet in Java. That means O(log(n)) theoretically, but if you just manipulate arrays of 20 elements it may not be worth it
If the set of all different elements is finite, like in your example where you just use numbers for 1 to 9, then there is a solution in O(1). Instead of having a sorted list you just keep an array with the number of occurrences of your elements.
If you still want to keep everything in an array, then the fastest way is this
find the position A of of the element you're going to remove by bisection in O(log(n)).
find the position B of where your new element is going to end up in the same way. More precisely B is the smallest index where new_element < a[k] for every k > B
if A < B, move all elements between A + 1 and B to their left, then set the new element to position B. if B > A, you do the same thing but to the right. Now this step is in O(n), but there's no logic, it's just moving memory around. In C you'd use memmove for this and it's heavily optimized, but I don't know any Java equivalent.
You don't need to sort it again.
Only one element changes. So you just need to go through the list and put the changed number to appropriate place. This will be of O(n) complexity.
int a[] = {1, 5, 2, 3, 3, 4, 5, 6, 7, 8, 9};
int count = 0;
//find the odd element
for(int jj=1; jj< a.length; jj++){
if(a[jj] < a[count])
break;
else count++;
}
System.out.println(" Odd position " + count);
//put odd element to proper position
for(int k= count+1; k<a.length; k++){
if(a[count] > a[k]){
int t = a[count];
a[count] = a[k];
a[k] = t;
count++;
}
}
Above is the working code tested for given input.
Enjoy.
Bubblesort is quite OK in this case with 20 compares max.
But finding the new position with binary search is O(log(n)), that is 5 compares in this case.
Somewhat faster, if you need the last bit odd speed use the binary search otherwise you can stick with bubble sort.
Here is a naive implementation in plain C. Remove the fprintf(stderr, ... after testing. The ITEM can be anything, as long as a comparison function is possible. Otherwise: use pointers to ITEM, (and maybe add an extra sizeofelem argument, ala qsort)
#include <stdio.h>
#include <string.h>
typedef int ITEM;
int item_cmp(ITEM one, ITEM two);
unsigned one_bubble( ITEM *arr, unsigned cnt, unsigned hot , int (*cmp)(ITEM,ITEM) );
int item_cmp(ITEM one, ITEM two)
{
fprintf(stderr,"Cmp= %u to %u: %d\n", one, two, one-two);
if (one > two) return 1;
else if (one < two) return -1;
else return 0;
}
unsigned one_bubble( ITEM *arr, unsigned cnt, unsigned hot , int (*cmp)(ITEM,ITEM) )
{
unsigned goal = cnt;
int diff;
ITEM temp;
/* hot element should move to the left */
if (hot > 0 && (diff=cmp( arr[hot-1], arr[hot])) > 0) {
/* Find place to insert (this could be a binary search) */
for (goal= hot; goal-- > 0; ) {
diff=cmp( arr[goal], arr[hot]);
if (diff <= 0) break;
}
goal++;
fprintf(stderr,"Move %u LEFT to %u\n", hot, goal);
if (goal==hot) return hot;
temp = arr[hot];
/* shift right */
fprintf(stderr,"memmove(%u,%u,%u)\n", goal+1, goal, (hot-goal) );
memmove(arr+goal+1, arr+goal, (hot-goal) *sizeof temp);
arr[goal] = temp;
return goal; /* new position */
}
/* hot element should move to the right */
else if (hot < cnt-1 && (diff=cmp( arr[hot], arr[hot+1])) > 0) {
/* Find place to insert (this could be a binary search) */
for (goal= hot+1; goal < cnt; goal++ ) {
diff=cmp( arr[hot], arr[goal]);
if (diff <= 0) break;
}
goal--;
fprintf(stderr,"Move %u RIGHT to %u\n", hot, goal);
if (goal==hot) return hot;
temp = arr[hot];
/* shift left */
fprintf(stderr,"memmove(%u,%u,%u)\n", hot, hot+1, (goal-hot) );
memmove(arr+hot, arr+hot+1, (goal-hot) *sizeof temp);
arr[goal] = temp;
return goal; /* new position */
}
fprintf(stderr,"Diff=%d Move %u Not to %u\n", diff, hot, goal);
return hot;
}
ITEM array[10] = { 1,10,2,3,4,5,6,7,8,9,};
#define HOT_POS 1
int main(void)
{
unsigned idx;
idx = one_bubble(array, 10, HOT_POS, item_cmp);
printf("%u-> %u\n", HOT_POS, idx );
for (idx = 0; idx < 10; idx++) {
printf("%u: %u\n", idx, array[idx] );
}
return 0;
}