if array is sorted then how to stop sorting .Time complexity 0(1) for the sorted array by selection sort.
static void sort(int a[]){
int min;
for(int i=0;i<a.length-1;i++){
min=i;
for(int j=i+1;j<a.length;j++)
{
if(a[j]<a[min])
min=j;
}
if(min==0){
System.out.print("min" + min);
break;
}
int temp=a[min];
a[min]=a[i];
a[i]=temp;
}
System.out.print(Arrays.toString(a) );
}
What you have there is a Selection sort, which does not lend itself easily to an "early out" when the array is sorted.
Think about what it's doing:
Find the smallest item in the array and place it in position 0.
Find the smallest remaining item and place it in position 1.
Repeat, finding the kth smallest item and placing it in position k, until k = n.
The algorithm doesn't make any comparisons to see if the rest of the array is in order.
I suppose you could add such a thing:
static void sort(int a[]) {
for(int i=0;i<a.length-1;i++){
Boolean isSorted = true;
Boolean didExchange = false;
int min=i;
for(int j=i+1;j<a.length;j++)
{
if(a[j]<a[min])
{
min=j;
}
if (a[j] < a[j-1])
{
// if at any point an item is smaller than its predecessor,
// then the array is not sorted.
isSorted = false;
}
}
if (min != i)
{
didExchange = true;
int temp=a[min];
a[min]=a[i];
a[i]=temp;
}
// If no exchange was made, and isSorted is still true,
// then the array is sorted.
if (isSorted && !didExchange)
{
break;
}
}
System.out.print(Arrays.toString(a) );
}
That makes for some messy code. Selection sort is among the most inefficient of the standard O(n^2) sorting algorithms. Both Bubble sort and Insertion sort have better real-world performance, and both much more easily modified to detect an already sorted array. In fact, you don't need to modify Insertion sort at all; the "early out" is just part of the basic algorithm.
By the way, even if the array is sorted, this will require O(n). You can't determine if an array is sorted in O(1), because you have to examine all n items.
I'm trying to solve a slightly different variation of the Maximum Sub-Set Sum problem. Instead of consecutive elements, I want to find the elements that gives you the largest sum in the array. For example, given the following array:
{1,-3,-5,3,2,-7,1} the output should be 7 ( the sub-array with largest sum is {1,3,2,1} ).
Here the code I use to calculate the max sum:
int max(int a, int b)
{
if (a >= b)
return a;
return b;
}
int func(List<Integer> l, int idx, int sum)
{
if (idx < 0)
return sum;
return max ( func(l,idx - 1, sum+l.get(idx)), func(l,idx-1,sum) );
}
public static void main(String[] args) {
List<Integer> l = new LinkedList<Integer>();
l.add(-2);
l.add(-1);
l.add(-3);
l.add(-4);
l.add(-1);
l.add(-2);
l.add(-1);
l.add(-5);
System.out.println(func(l,l.size()-1,0));
}
It works when I use positive and negative numbers together in the same array. However, the problem starts when I use only negative numbers - the output always is 0. I guess it happens because I send 0 as the sum at the very first time when I call the function. Can someone tell me how should I change my function so it will work with only negative numbers as well.
Your solution is unnecessarily complicated and inefficient (it has an O(2^n) time complexity).
Here's a simple and efficient (O(N) time, O(1) extra space) way to do it:
If there's at least one non-negative number in the list, return the sum of all positive numbers.
Return the largest element in the list otherwise.
Here's some code:
def get_max_non_empty_subset_sum(xs):
max_elem = max(xs)
if max_elem < 0:
return max_elem
return sum(x for x in xs if x > 0)
The special case would be when all elements are negative. In this case find the least negative number. That would be your answer. This can be done in O(N) time complexity.
PSEUDO CODE
ALLNEG=true
LEAST_NEG= -INFINITY
for number in list:
if number>=0
ALLNEG=false
break
else if number>LEAST_NEG
LEAST_NEG=number
if ALLNEG==true
answer=LEAST_NEG
else
...
Given a sorted array A, which stores n integers, and a value key. Design
an efficient divide and conquer algorithm that returns the index of the value
key if it can be found in array A.Otherwise, the algorithm returns 0.
I think for your description that the best choice is binary search (dichotomous search). The algorithm is to go by dividing the array in half and buying if the element found in the middle is higher, lower or equal to the item you are looking for. This is done in order to reduce search space to find the element logarithmically or determine that the element is not in the vector.The array must be ordered.
this is an example in C++
#include <vector>
bool busqueda_dicotomica(const vector<int> &v, int principio, int fin, int &x){
bool res;
if(principio <= fin){
int m = ((fin - principio)/2) + principio;
if(x < v[m]) res = busqueda_dicotomica(v, principio, m-1, x);
else if(x > v[m]) res = busqueda_dicotomica(v, m+1, fin, x);
else res = true;
}else res = false;
return res;
}
I think your algorithm should not return 0 if not found because if you want to return the index of the element, 0 is the index of the first element
In this article is the detailed explanation of the binary search or in this other
I got the following recursive algorithm and was asked to find its recurrence relation.
int search(int A[], int key, int min, int max)
{
if (max < min) // base case
return KEY_NOT_FOUND;
else
{
int mid = midpoint(min, max);
if (A[mid] > key)
return search(A, key, min, mid-1);
else if (A[mid] < key)
return search(A, key, mid+1, max);
else
return mid; // key found
}
}
The solution is T(n) = T(n/2) + 1 but I am not sure why is it T(n/2) ? and why is it + 1? Is + 1 because recursion takes constant time? or what? Could anyone understand the solution?
Your code is an implementation of binary search. In binary search, at each recursive call you break the sorted array into half, then search for the element in the left part of the array if the element is smaller than the middle element, or search the right part of the array if the element is bigger than the middle element or stop if what you are looking for is the middle element.
Now if n shows the number of elements in your sorted array, whenever you break it into two almost same size arrays, your problem size decreases to n/2, and since you only call the search function once either way on a n/2 array, you can easily say that :
T(n) = T(n/2)+O(1)
The O(1) addition is because of the if you run to check in which condition you are.
Given a list of integers, how can I best find an integer that is not in the list?
The list can potentially be very large, and the integers might be large (i.e. BigIntegers, not just 32-bit ints).
If it makes any difference, the list is "probably" sorted, i.e. 99% of the time it will be sorted, but I cannot rely on always being sorted.
Edit -
To clarify, given the list {0, 1, 3, 4, 7}, examples of acceptable solutions would be -2, 2, 8 and 10012, but I would prefer to find the smallest, non-negative solution (i.e. 2) if there is an algorithm that can find it without needing to sort the entire list.
One easy way would be to iterate the list to get the highest value n, then you know that n+1 is not in the list.
Edit:
A method to find the smallest positive unused number would be to start from zero and scan the list for that number, starting over and increase if you find the number. To make it more efficient, and to make use of the high probability of the list being sorted, you can move numbers that are smaller than the current to an unused part of the list.
This method uses the beginning of the list as storage space for lower numbers, the startIndex variable keeps track of where the relevant numbers start:
public static int GetSmallest(int[] items) {
int startIndex = 0;
int result = 0;
int i = 0;
while (i < items.Length) {
if (items[i] == result) {
result++;
i = startIndex;
} else {
if (items[i] < result) {
if (i != startIndex) {
int temp = items[startIndex];
items[startIndex] = items[i];
items[i] = temp;
}
startIndex++;
}
i++;
}
}
return result;
}
I made a performance test where I created lists with 100000 random numbers from 0 to 19999, which makes the average lowest number around 150. On test runs (with 1000 test lists each), the method found the smallest number in unsorted lists by average in 8.2 ms., and in sorted lists by average in 0.32 ms.
(I haven't checked in what state the method leaves the list, as it may swap some items in it. It leaves the list containing the same items, at least, and as it moves smaller values down the list I think that it should actually become more sorted for each search.)
If the number doesn't have any restrictions, then you can do a linear search to find the maximum value in the list and return the number that is one larger.
If the number does have restrictions (e.g. max+1 and min-1 could overflow), then you can use a sorting algorithm that works well on partially sorted data. Then go through the list and find the first pair of numbers v_i and v_{i+1} that are not consecutive. Return v_i + 1.
To get the smallest non-negative integer (based on the edit in the question), you can either:
Sort the list using a partial sort as above. Binary search the list for 0. Iterate through the list from this value until you find a "gap" between two numbers. If you get to the end of the list, return the last value + 1.
Insert the values into a hash table. Then iterate from 0 upwards until you find an integer not in the list.
Unless it is sorted you will have to do a linear search going item by item until you find a match or you reach the end of the list. If you can guarantee it is sorted you could always use the array method of BinarySearch or just roll your own binary search.
Or like Jason mentioned there is always the option of using a Hashtable.
"probably sorted" means you have to treat it as being completely unsorted. If of course you could guarantee it was sorted this is simple. Just look at the first or last element and add or subtract 1.
I got 100% in both correctness & performance,
You should use quick sorting which is N log(N) complexity.
Here you go...
public int solution(int[] A) {
if (A != null && A.length > 0) {
quickSort(A, 0, A.length - 1);
}
int result = 1;
if (A.length == 1 && A[0] < 0) {
return result;
}
for (int i = 0; i < A.length; i++) {
if (A[i] <= 0) {
continue;
}
if (A[i] == result) {
result++;
} else if (A[i] < result) {
continue;
} else if (A[i] > result) {
return result;
}
}
return result;
}
private void quickSort(int[] numbers, int low, int high) {
int i = low, j = high;
int pivot = numbers[low + (high - low) / 2];
while (i <= j) {
while (numbers[i] < pivot) {
i++;
}
while (numbers[j] > pivot) {
j--;
}
if (i <= j) {
exchange(numbers, i, j);
i++;
j--;
}
}
// Recursion
if (low < j)
quickSort(numbers, low, j);
if (i < high)
quickSort(numbers, i, high);
}
private void exchange(int[] numbers, int i, int j) {
int temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
}
Theoretically, find the max and add 1. Assuming you're constrained by the max value of the BigInteger type, sort the list if unsorted, and look for gaps.
Are you looking for an on-line algorithm (since you say the input is arbitrarily large)? If so, take a look at Odds algorithm.
Otherwise, as already suggested, hash the input, search and turn on/off elements of boolean set (the hash indexes into the set).
There are several approaches:
find the biggest int in the list and store it in x. x+1 will not be in the list. The same applies with using min() and x-1.
When N is the size of the list, allocate an int array with the size (N+31)/32. For each element in the list, set the bit v&31 (where v is the value of the element) of the integer at array index i/32. Ignore values where i/32 >= array.length. Now search for the first array item which is '!= 0xFFFFFFFF' (for 32bit integers).
If you can't guarantee it is sorted, then you have a best possible time efficiency of O(N) as you have to look at every element to make sure your final choice is not there. So the question is then:
Can it be done in O(N)?
What is the best space efficiency?
Chris Doggett's solution of find the max and add 1 is both O(N) and space efficient (O(1) memory usage)
If you want only probably the best answer then it is a different question.
Unless you are 100% sure it is sorted, the quickest algorithm still has to look at each number in the list at least once to at least verify that a number is not in the list.
Assuming this is the problem I'm thinking of:
You have a set of all ints in the range 1 to n, but one of those ints is missing. Tell me which of int is missing.
This is a pretty easy problem to solve with some simple math knowledge. It's known that the sum of the range 1 .. n is equal to n(n+1) / 2. So, let W = n(n+1) / 2 and let Y = the sum of the numbers in your set. The integer that is missing from your set, X, would then be X = W - Y.
Note: SO needs to support MathML
If this isn't that problem, or if it's more general, then one of the other solutions is probably right. I just can't really tell from the question since it's kind of vague.
Edit: Well, since the edit, I can see that my answer is absolutely wrong. Fun math, none-the-less.
I've solved this using Linq and a binary search. I got 100% across the board. Here's my code:
using System.Collections.Generic;
using System.Linq;
class Solution {
public int solution(int[] A) {
if (A == null) {
return 1;
} else {
if (A.Length == 0) {
return 1;
}
}
List<int> list_test = new List<int>(A);
list_test = list_test.Distinct().ToList();
list_test = list_test.Where(i => i > 0).ToList();
list_test.Sort();
if (list_test.Count == 0) {
return 1;
}
int lastValue = list_test[list_test.Count - 1];
if (lastValue <= 0) {
return 1;
}
int firstValue = list_test[0];
if (firstValue > 1) {
return 1;
}
return BinarySearchList(list_test);
}
int BinarySearchList(List<int> list) {
int returnable = 0;
int tempIndex;
int[] boundaries = new int[2] { 0, list.Count - 1 };
int testCounter = 0;
while (returnable == 0 && testCounter < 2000) {
tempIndex = (boundaries[0] + boundaries[1]) / 2;
if (tempIndex != boundaries[0]) {
if (list[tempIndex] > tempIndex + 1) {
boundaries[1] = tempIndex;
} else {
boundaries[0] = tempIndex;
}
} else {
if (list[tempIndex] > tempIndex + 1) {
returnable = tempIndex + 1;
} else {
returnable = tempIndex + 2;
}
}
testCounter++;
}
if (returnable == list[list.Count - 1]) {
returnable++;
}
return returnable;
}
}
The longest execution time was 0.08s on the Large_2 test
You need the list to be sorted. That means either knowing it is sorted, or sorting it.
Sort the list. Skip this step if the list is known to be sorted. O(n lg n)
Remove any duplicate elements. Skip this step if elements are already guaranteed distinct. O(n)
Let B be the position of 1 in the list using a binary search. O(lg n)
If 1 isn't in the list, return 1. Note that if all elements from 1 to n are in the list, then the element at B+n must be n+1. O(1)
Now perform a sortof binary search starting with min = B, max = end of the list. Call the position of the pivot P. If the element at P is greater than (P-B+1), recurse on the range [min, pivot], otherwise recurse on the range (pivot, max]. Continue until min=pivot=max O(lg n)
Your answer is (the element at pivot-1)+1, unless you are at the end of the list and (P-B+1) = B in which case it is the last element + 1. O(1)
This is very efficient if the list is already sorted and has distinct elements. You can do optimistic checks to make it faster when the list has only non-negative elements or when the list doesn't include the value 1.
Just gave an interview where they asked me this question. The answer to this problem can be found using worst case analysis. The upper bound for the smallest natural number present on the list would be length(list). This is because, the worst case for the smallest number present in the list given the length of the list is the list 0,1,2,3,4,5....length(list)-1.
Therefore for all lists, smallest number not present in the list is less than equal to length of the list. Therefore, initiate a list t with n=length(list)+1 zeros. Corresponding to every number i in the list (less than equal to the length of the list) mark assign the value 1 to t[i]. The index of the first zero in the list is the smallest number not present in the list. And since, the lower bound on this list n-1, for at least one index j