Related
Given an array of N positive numbers, the task is to find a contiguous subarray (L-R) such that a[L]=a[R] and sum of a[L] + a[L+1] +…+ a[R] is maximum. If array doesn't have same numbers return -1.
For example:
Input: arr[] = {1, 3, 2, 2, 3}
Output: 10
Subarray [3, 2, 2, 3] starts and ends with 3 and has sum = 10
Input: arr[] = {5,1,4,3}
Output: -1
public int solution(int[] A) {
// write your code in Java SE 8
int n = A.length;
HashMap<Integer, Integer> first = new HashMap<>();
HashMap<Integer, Integer> last = new HashMap<>();
int[] prefix = new int[n];
for (int i = 0; i < n; i++) {
// Build prefix sum array
if (i != 0)
prefix[i] = prefix[i - 1] + A[i];
else
prefix[i] = A[i];
// If the value hasn't been encountered before,
// It is the first occurrence
if (!first.containsKey(A[i]))
first.put(A[i], i);
// Keep updating the last occurrence
last.put(A[i], i);
}
int ans = -1;
// Find the maximum sum with same first and last
// value
for (int i = 0; i < n; i++) {
int start = first.get(A[i]);
int end = last.get(A[i]);
int sum = 0;
if(start == 0)
sum = prefix[end];
else
sum = prefix[end] - prefix[start - 1];
if(sum > ans)
ans = sum;
}
return ans;
}
it doesn't return -1 for the example: arr[] = {5,1,4,3}.
Try this.
public static int solution(int[] array) {
Map<Integer, Integer> map = new HashMap<>();
int max = -1;
for (int i = 0, size = array.length; i < size; ++i) {
int value = array[i];
Integer start = map.get(value);
if (start != null)
max = Math.max(max, IntStream.rangeClosed(start, i).map(j -> array[j]).sum());
else
map.put(value, i);
}
return max;
}
public static void main(String[] args) {
System.out.println(solution(new int[] {1, 3, 2, 2, 3}));
System.out.println(solution(new int[] {5, 1, 4, 3}));
}
output:
10
-1
that, given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A.
For example, given A = [1, 3, 6, 4, 1, 2], the function should return 5.
Given A = [1, 2, 3], the function should return 4.
Given A = [−1, −3], the function should return 1.
Write an efficient algorithm for the following assumptions:
import java.util.*;
class Main {
/* Utility function that puts all non-positive
(0 and negative) numbers on left side of
arr[] and return count of such numbers */
static int segregate(int arr[], int size)
{
int j = 0, i;
for (i = 0; i < size; i++) {
if (arr[i] <= 0) {
int temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
// increment count of non-positive
// integers
j++;
}
}
return j;
}
/* Find the smallest positive missing
number in an array that contains
all positive integers */
static int findMissingPositive(int arr[], int size)
{
int i;
// Mark arr[i] as visited by making
// arr[arr[i] - 1] negative. Note that
// 1 is subtracted because index start
// from 0 and positive numbers start from 1
for (i = 0; i < size; i++) {
int x = Math.abs(arr[i]);
if (x - 1 < size && arr[x - 1] > 0)
arr[x - 1] = -arr[x - 1];
}
// Return the first index value at which
// is positive
for (i = 0; i < size; i++)
if (arr[i] > 0)
return i + 1; // 1 is added becuase indexes
// start from 0
return size + 1;
}
/* Find the smallest positive missing
number in an array that contains
both positive and negative integers */
static int findMissing(int arr[], int size)
{
// First separate positive and
// negative numbers
int shift = segregate(arr, size);
int arr2[] = new int[size - shift];
int j = 0;
for (int i = shift; i < size; i++) {
arr2[j] = arr[i];
j++;
}
// Shift the array and call
// findMissingPositive for
// positive part
return findMissingPositive(arr2, j);
}
// main function
public static void main(String[] args)
{
int arr[] = { 0, 10, 2, -10, -20 };
int arr_size = arr.length;
int missing = findMissing(arr, arr_size);
System.out.println("The smallest positive missing number is " + missing);
}
}
}
If you need to use stream, the more straightfoward, but not optimal way to do it is to create an infinite stream, starting at 1 and return the first that is not in arr:
int[] arr = { 1, 3, 6, 4, 1, 2 };
Set<Integer> arrSet = Arrays.stream(arr).boxed().collect(Collectors.toSet());
Optional<Integer> found = IntStream.iterate(1, o -> o + 1).boxed()
.filter(value -> !arrSet.contains(value))
.findFirst();
found.ifPresent(System.out::println);
Output
5
As pointed out this is very inefficient, but in terms of computational complexity I believe is optimal, at least for the worst case i.e. the one you have to look at all the elements.
Below you can find the missing positive integer using Streams -
int ar[] = { 0, 10, 2, -10, -20 };
int max = Arrays.stream(ar).max().getAsInt();
System.err.println("maxvalue "+max);
int val = IntStream.range(1, max).filter(i->!Arrays.stream(ar).anyMatch(x->x==i))
.findFirst().getAsInt();
System.out.println(val);
int[] val1 = IntStream.range(1, max).filter(i->!Arrays.stream(ar).anyMatch(x->x==i)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(val1).forEach(System.out::println);
int[] valEven = IntStream.range(1, max).filter(i->Arrays.stream(val1).anyMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valEven).forEach(System.out::println);
int[] valOdd = IntStream.range(1, max).filter(i->!Arrays.stream(val1).anyMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valOdd).forEach(System.out::println);
int[] valOdd1 = IntStream.range(1, max).filter(i->Arrays.stream(val1).noneMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valOdd1).forEach(System.out::println);
int[] valEven1 = IntStream.range(1, max).filter(i->!Arrays.stream(val1).noneMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valEven1).forEach(System.out::println);
You can also do a mix of stream and primitive int loop:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] numberSet1 = {1, 3, 6, 4, 1, 2};
int[] numberSet2 = {-1, -3};
int[] numberSet3 = {1, 2, 3};
System.out.println(calcularPrimero(numberSet1));
System.out.println(calcularPrimero(numberSet2));
System.out.println(calcularPrimero(numberSet3));
}
public static int calcularPrimero (int[] A) {
//IntStream intStream = Arrays.stream(A).filter(x -> x >= 0).distinct().sorted();
int[] B = Arrays.stream(A).filter(x -> x > 0).distinct().sorted().toArray();
for (int i = 0, index = 1; i < B.length; i++, index++) {
if (index != B[i]) {
return index;
}
}
return B.length + 1;
}
}
I have the following codes and instead of typing the numbers using scanner function. I want to use an array instead . How do I do this? I need help. Thanks in advance
public class salomon {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] a = new int[n];
int[] minHeap = new int[n];
int[] maxHeap = new int[n];
int minHeapSize = 0;
int maxHeapSize = 0;
float currentMedian = 0;
for (int a_i = 0; a_i < n; a_i++) {
a[a_i] = in.nextInt();
if (a[a_i] < currentMedian) {
maxHeap[maxHeapSize++] = a[a_i];
// making sure the max heap has maximum value at the top
if (maxHeap[maxHeapSize - 1] > maxHeap[0]) {
swap(maxHeap, maxHeapSize - 1, 0);
}
} else {
minHeap[minHeapSize++] = a[a_i];
// making sure the min heap has minimum value at the top
if (minHeap[minHeapSize - 1] < minHeap[0]) {
swap(minHeap, minHeapSize - 1, 0);
}
}
// if the difference is more than one
if (Math.abs(maxHeapSize - minHeapSize) > 1) {
if (maxHeapSize > minHeapSize) {
swap(maxHeap, maxHeapSize - 1, 0);
minHeap[minHeapSize++] = maxHeap[--maxHeapSize];
swap(minHeap, 0, minHeapSize - 1);
buildMaxHeap(maxHeap, maxHeapSize);
} else {
swap(minHeap, minHeapSize - 1, 0);
maxHeap[maxHeapSize++] = minHeap[--minHeapSize];
swap(maxHeap, 0, maxHeapSize - 1);
buildMinHeap(minHeap, minHeapSize);
}
}
// calculate the median
if (maxHeapSize == minHeapSize) {
currentMedian = (minHeap[0] + maxHeap[0]);
currentMedian = currentMedian / 2;
} else if (maxHeapSize > minHeapSize) {
currentMedian = maxHeap[0];
} else {
currentMedian = minHeap[0];
}
System.out.println(currentMedian);
}
}
static void buildMaxHeap(int[] input, int heapSize) {
int depth = (heapSize - 1) / 2;
for (int i = depth; i >= 0; i--) {
maxHeapify(input, i, heapSize);
}
}
static void maxHeapify(int[] input, int i, int heapSize) {
int left = 2 * i + 1;
int right = 2 * i + 2;
// find the largest
int largest = i;
if (left < heapSize && input[left] > input[largest]) {
largest = left;
}
if (right < heapSize && input[right] > input[largest]) {
largest = right;
}
if (largest != i) {
//swap
swap(input, i, largest);
//recursive call
maxHeapify(input, largest, heapSize);
}
}
static void buildMinHeap(int[] input, int heapSize) {
int depth = (heapSize - 1) / 2;
for (int i = depth; i >= 0; i--) {
minHeapify(input, i, heapSize);
}
}
static void minHeapify(int[] input, int i, int heapSize) {
int left = 2 * i + 1;
int right = 2 * i + 2;
// find the smallest
int smallest = i;
if (left < heapSize && input[left] < input[smallest]) {
smallest = left;
}
if (right < heapSize && input[right] < input[smallest]) {
smallest = right;
}
if (smallest != i) {
//swap
swap(input, i, smallest);
//recursive call
minHeapify(input, smallest, heapSize);
}
}
static void swap(int[] input, int i, int j) {
if (i == j)
return;
int temp = input[i];
input[i] = input[j];
input[j] = temp;
}
}
When I typed 6, 12, 4, 5, 3, 8, 7 and enter - I get the Moving median
12.0
8.0
5.0
4.5
5.0
6.0
I want to replace the scanner with an array {6, 12, 4, 5, 3, 8, 7}`
instead and how do I adjust the code. Thanks
The first value 6 is the array length. Assuming you intend for that to remain, you would remove everything that "isn't an elephant" (namely all of the median calculations), and rename int[] a to int[] f. Like,
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] f = new int[n];
for (int i = 0; i < n; i++) {
f[i] = in.nextInt();
}
System.out.println(Arrays.toString(f));
}
When executed with your example input, this outputs
[12, 4, 5, 3, 8, 7]
If you really did want the six as well, then you would need to add it. Like,
int[] f = new int[n + 1];
f[0] = n;
for (int i = 1; i <= n; i++) {
f[i] = in.nextInt();
}
System.out.println(Arrays.toString(f));
which outputs (as requested)
[6, 12, 4, 5, 3, 8, 7]
public static void main(String[] args) {
int arr[]= {0,-1,2,-3,5,9,-5,10};
int max_ending_here=0;
int max_so_far=0;
int start =0;
int end=0;
for(int i=0;i< arr.length;i++)
{
max_ending_here=max_ending_here+arr[i];
if(max_ending_here<0)
{
max_ending_here=0;
}
if(max_so_far<max_ending_here){
max_so_far=max_ending_here;
}
}
System.out.println(max_so_far);
}
}
this program generates the max sum of sub array ..in this case its 19,using {5,9,-5,10}..
now i have to find the start and end index of this sub array ..how do i do that ??
This is a C program to solve this problem. I think logic is same for all languages so I posted this answer.
void findMaxSubArrayIndex(){
int n,*a;
int start=0,end=0,curr_max=0,prev_max=0,start_o=0,i;
scanf("%d",&n);
a = (int*)malloc(sizeof(int)*n);
for(i=0; i<n; i++) scanf("%d",a+i);
prev_max = a[0];
for(i=0; i<n; i++){
curr_max += a[i];
if(curr_max < 0){
start = i+1;
curr_max = 0;
}
else if(curr_max > prev_max){
end = i;
start_o = start;
prev_max = curr_max;
}
}
printf("%d %d \n",start_o,end);
}
Fixing Carl Saldanha solution:
int max_ending_here = 0;
int max_so_far = 0;
int _start = 0;
int start = 0;
int end = -1;
for(int i=0; i<array.length; i++) {
max_ending_here = max_ending_here + array[i];
if (max_ending_here < 0) {
max_ending_here = 0;
_start = i+1;
}
if (max_ending_here > max_so_far) {
max_so_far = max_ending_here;
start = _start;
end = i;
}
}
Here is algorithm for maxsubarray:
public class MaxSubArray {
public static void main(String[] args) {
int[] intArr={3, -1, -1, -1, -1, -1, 2, 0, 0, 0 };
//int[] intArr = {-1, 3, -5, 4, 6, -1, 2, -7, 13, -3};
//int[] intArr={-6,-2,-3,-4,-1,-5,-5};
findMaxSubArray(intArr);
}
public static void findMaxSubArray(int[] inputArray){
int maxStartIndex=0;
int maxEndIndex=0;
int maxSum = Integer.MIN_VALUE;
int cumulativeSum= 0;
int maxStartIndexUntilNow=0;
for (int currentIndex = 0; currentIndex < inputArray.length; currentIndex++) {
int eachArrayItem = inputArray[currentIndex];
cumulativeSum+=eachArrayItem;
if(cumulativeSum>maxSum){
maxSum = cumulativeSum;
maxStartIndex=maxStartIndexUntilNow;
maxEndIndex = currentIndex;
}
if (cumulativeSum<0){
maxStartIndexUntilNow=currentIndex+1;
cumulativeSum=0;
}
}
System.out.println("Max sum : "+maxSum);
System.out.println("Max start index : "+maxStartIndex);
System.out.println("Max end index : "+maxEndIndex);
}
}
Here is a solution in python - Kadane's algorithm extended to print the start/end indexes
def max_subarray(array):
max_so_far = max_ending_here = array[0]
start_index = 0
end_index = 0
for i in range(1, len(array) -1):
temp_start_index = temp_end_index = None
if array[i] > (max_ending_here + array[i]):
temp_start_index = temp_end_index = i
max_ending_here = array[i]
else:
temp_end_index = i
max_ending_here = max_ending_here + array[i]
if max_so_far < max_ending_here:
max_so_far = max_ending_here
if temp_start_index != None:
start_index = temp_start_index
end_index = i
print max_so_far, start_index, end_index
if __name__ == "__main__":
array = [-2, 1, -3, 4, -1, 2, 1, 8, -5, 4]
max_subarray(array)
In python solving 3 problem i.e., sum, array elements and index.
def max_sum_subarray(arr):
current_sum = arr[0]
max_sum = arr[0]
curr_array = [arr[0]]
final_array=[]
s = 0
start = 0
e = 0
end = 0
for i in range(1,len(arr)):
element = arr[i]
if current_sum+element > element:
curr_array.append(element)
current_sum = current_sum+element
e += 1
else:
curr_array = [element]
current_sum = element
s = i
if current_sum > max_sum:
final_array = curr_array[:]
start = s
end = e
max_sum = current_sum
print("Original given array is : ", arr)
print("The array elements that are included in the sum are : ",final_array)
print("The starting and ending index are {} and {} respectively.".format(start, end))
print("The maximum sum is : ", max_sum)
# Driver code
arr = [-12, 15, -13, 14, -1, 2, 1, -5, 4]
max_sum_subarray(arr)
By Om Prasad Nayak
Like This
public static void main(String[] args) {
int arr[]= {0,-1,2,-3,5,9,-5,10};
int max_ending_here=0;
int max_so_far=0;
int start =0;
int end=0;
for(int i=0;i< arr.length;i++){
max_ending_here=max_ending_here+arr[i];
if(max_ending_here<0)
{
start=i+1; //Every time it goes negative start from next index
max_ending_here=0;
}
else
end =i; //As long as its positive keep updating the end
if(max_so_far<max_ending_here){
max_so_far=max_ending_here;
}
}
System.out.println(max_so_far);
}
Okay so there was a problem in the above solution as pointed to Steve P. This is another solution which should work for all
public static int[] compareSub(int arr[]){
int start=-1;
int end=-1;
int max=0;
if(arr.length>0){
//Get that many array elements and compare all of them.
//Then compare their max to the overall max
start=0;end=0;max=arr[0];
for(int arrSize=1;arrSize<arr.length;arrSize++){
for(int i=0;i<arr.length-arrSize+1;i++){
int potentialMax=sumOfSub(arr,i,i+arrSize);
if(potentialMax>max){
max=potentialMax;
start=i;
end=i+arrSize-1;
}
}
}
}
return new int[]{start,end,max};
}
public static int sumOfSub(int arr[],int start,int end){
int sum=0;
for(int i=start;i<end;i++)
sum+=arr[i];
return sum;
}
The question is somewhat unclear but I'm guessing a "sub-array" is half the arr object.
A lame way to do this like this
public int sum(int[] arr){
int total = 0;
for(int index : arr){
total += index;
}
return total;
}
public void foo(){
int arr[] = {0,-1,2,-3,5,9,-5,10};
int subArr1[] = new int[(arr.length/2)];
int subArr2[] = new int[(arr.length/2)];
for(int i = 0; i < arr.length/2; i++){
// Lazy hack, might want to double check this...
subArr1[i] = arr[i];
subArr2[i] = arr[((arr.length -1) -i)];
}
int sumArr1 = sum(subArr1);
int sumArr2 = sum(subArr2);
}
I image this might not work if the arr contains an odd number of elements.
If you want access to a higher level of support convert the primvate arrays to a List object
List<Integer> list = Arrays.asList(arr);
This way you have access to a collection object functionality.
Also if you have the time, take a look at the higher order functional called reduce. You will need a library that supports functional programming. Guava or lambdaJ might have a reduce method. I know that apache-commons lacks one, unless you want to hack to together it.
The only thing I have to add (to several solutions posted here) is to cover the case that all the integers are negative, in which case the max sub array will be just the max element. Pretty easy to do that.. just have to track max element and index of the index of the max element as you iterate through it. If the max element is negative, return it's index instead.
There is also the case of overflow to possibly handle. I've seen algorithm tests that take than into account.. IE, suppose MAXINT was one of the elements and you tried to add to it. I believe some of the Codility (coding interview screeners) tests take that into account.
public static void maxSubArray(int []arr){
int sum=0,j=0;
int temp[] = new int[arr.length];
for(int i=0;i<arr.length;i++,j++){
sum = sum + arr[i];
if(sum <= 0){
sum =0;
temp[j] = -1;
}else{
temp[j] = i;
}
}
rollback(temp,arr);
}
public static void rollback(int [] temp , int[] arr){
int s =0,start=0 ;
int maxTillNow = 0,count =0;
String str1 = "",str2="";
System.out.println("============");
// find the continuos index
for(int i=0;i<temp.length;i++){
if(temp[i] != -1){
s += arr[temp[i]];
if(s > maxTillNow){
if(count == 0){
str1 = "" + start;
}
count++;
maxTillNow = s;
str2 = " " + temp[i];
}
}else{
s=0;
count =0;
if(i != temp.length-1)
start = temp[i+1];
}
}
System.out.println("Max sum will be ==== >> " + maxTillNow);
System.out.print("start from ---> "+str1 + " end to --- >> " +str2);
}
public void MaxSubArray(int[] arr)
{
int MaxSoFar = 0;
int CurrentMax = 0;
int ActualStart=0,TempStart=0,End = 0;
for(int i =0 ; i<arr.Length;i++)
{
CurrentMax += arr[i];
if(CurrentMax<0)
{
CurrentMax = 0;
TempStart = i + 1;
}
if(MaxSoFar<CurrentMax)
{
MaxSoFar = CurrentMax;
ActualStart = TempStart;
End = i;
}
}
Console.WriteLine(ActualStart.ToString()+End.ToString());
}
An O(n) solution in C would be :-
void maxsumindex(int arr[], int len)
{
int maxsum = INT_MIN, cur_sum = 0, start=0, end=0, max = INT_MIN, maxp = -1, flag = 0;
for(int i=0;i<len;i++)
{
if(max < arr[i]){
max = arr[i];
maxp = i;
}
cur_sum += arr[i];
if(cur_sum < 0)
{
cur_sum = 0;
start = i+1;
}
else flag = 1;
if(maxsum < cur_sum)
{
maxsum = cur_sum;
end = i;
}
}
//This is the case when all elements are negative
if(flag == 0)
{
printf("Max sum subarray = {%d}\n",arr[maxp]);
return;
}
printf("Max sum subarray = {");
for(int i=start;i<=end;i++)
printf("%d ",arr[i]);
printf("}\n");
}
Here is a solution in Go using Kadane's Algorithm
func maxSubArr(A []int) (int, int, int) {
start, currStart, end, maxSum := 0, 0, 0, A[0]
maxAtI := A[0]
for i := 1; i < len(A); i++ {
if maxAtI > 0 {
maxAtI += A[i]
} else {
maxAtI = A[i]
currStart = i
}
if maxAtI > maxSum {
maxSum = maxAtI
start = currStart
end = i
}
}
return start, end, maxSum
}
Here is a C++ solution.
void maxSubArraySum(int *a, int size) {
int local_max = a[0];
int global_max = a[0];
int sum_so_far = a[0];
int start = 0, end = 0;
int tmp_start = 0;
for (int i = 1; i < size; i++) {
sum_so_far = a[i] + local_max;
if (sum_so_far > a[i]) {
local_max = sum_so_far;
} else {
tmp_start = i;
local_max = a[i];
}
if (global_max < local_max) {
global_max = local_max;
start = tmp_start;
end = i;
}
}
cout<<"Start Index: "<<start<<endl;
cout<<"End Index: "<<end<<endl;
cout<<"Maximum Sum: "<<global_max<<endl;
}
int main() {
int arr[] = {4, -3, -2, 2, 3, 1, -2, -3, 4,2, -6, -3, -1, 3, 1, 2};
maxSubArraySum(arr, sizeof(arr)/sizeof(arr[0]));
return 0;
}
pair<int,int> maxSumPair(vector<int> arr) {
int n = arr.size();`
int currSum = arr[0], maxSoFar = arr[0];
int start = 0, end ,prev = currSum;
unordered_map<int,pair<int,int>> mp;
for(int i = 1 ; i < n ; i++) {
prev = currSum;
if(currSum == arr[i]) {
end = i-1;
mp.insert({currSum,{start,end}});
start = i;
}
if(maxSoFar < currSum) {
maxSoFar = currSum;
end = i;
mp.insert({currSum,{start,end}});
}
}
int maxSum = INT_MIN;
for(auto it: mp) {
if(it.first > maxSum) {
maxSum = it.first;
}
}
return mp[maxSum];
}
int maxSubarraySum(int arr[], int n){
int max_so_far = -1 * Integer.MAX_VALUE;
int max_curr = 0;
int start = 0;
int end = 0;
for(int i=0; i < arr.length; i++){
max_curr = max_curr + arr[i];
if(max_so_far < max_curr){
max_so_far = max_curr;
}
if( max_curr < 0){
max_curr = 0;
start = i+1;
}
else
end = i;
}
start = end < start ? end : start;
System.out.println( start + "..." + end);
return max_so_far;
}
Maximum sub array in golang implementation
package main
import (
"fmt"
)
func main() {
in := []int{-2, -12, 23, -10, 11, -6, -1}
a, b := max(in)
fmt.Println(a)
fmt.Println(b)
}
func max(in []int) ([]int, int) {
var p, r, sum, sf, psf int
if len(in) == 0 {
return in, 0
}
sum = in[0]
for i, n := range in {
sf += n
if sf > sum {
sum = sf
p = psf
r = i
}
if sf <= 0 {
psf = i + 1
sf = 0
}
}
return in[p : r+1], sum
}
I think this will help to get the start and end index
// Time Complexity = O(N)
// Space Complexity = O(1)
public static int maxSum2(int[] nums){
int globalSum = Integer.MIN_VALUE;
int currentSum = 0;
int start=0;
int end=0;
for(int i=0; i<nums.length;i++){
currentSum += nums[i];
if (currentSum>globalSum){
globalSum = currentSum;
end = i;
}
if (currentSum<0){
currentSum=0;
start = i+1;
}
}
System.out.println(start + " " + end);
return globalSum;
}
I am trying to create a method which returns an int - the value of the largest integer in the sent array.
The way I want this method to work, is to check the first and the last element of the array in a for-loop, and work their way to the middle. So i = first integer, k = last integer. When i = 0, k = n-1 (indexes), when i = 1, k = n-2 if you catch my drift. In every loop it needs to check if a[i]>a[k]. Then they switch places. Then I know that the largest number is in the leading half of the array, and then I want it to check that half, so ultimately the largest int is at index 0.
I tried like this:
public static int maxOfArray(int[] a)
{
int length = a.length;
if(length<1)
throw new NoSuchElementException("Not at least one integer in array");
while (length > 1)
{
int k = length;
for(int i = 0; i < length/2; i++)
{
k--;
if(a[i]<a[k])
{
int j = a[i];
a[i] = a[k];
a[k] = j;
}
}
length /=2;
}
return a[0];
}
..but I don't really get it.. I'm having a hard time "picturing" what's happening here.. But it's not always working.. (though sometimes).
EDIT
Also: The array {6,15,2,5,8,14,10,16,11,17,13,7,1,18,3,4,9,12}; will spit out 17 as the largest number. I realize I have to fix the odd-length bug, but I would like to solve this even-length array first..
A bug is when encountering length is odd.
In these cases, you "miss" the middle element.
Example: for input int[] arr = { 8, 1, 5, 4, 9, 4, 3, 7, 2 }; - the element 9 will be compared and checked against itself, but then you reduce the size of length, you exclude 9 from the array you are going to iterate next.
I believe it can be solved by reducing the problem to ceil(length/2) instead of length/2 (and handling special case of length==1)
The other issue as was mentioned in comments is: you need to iterate up to length/2 rather then up to length, otherwise you are overriding yourself.
Lastly - the sign is wrong.
if(a[i]>a[k])
should be
if(a[i]<a[k])
Remember - you are trying to swap the elements if the first is smaller the the second in order to push the larger elements to the head of your array.
but I don't really get it.. I'm having a hard time "picturing" what's happening here.. But it's not always working.. (though sometimes).
In that case you should use a debugger to step through the code to get a picture of what each line of code does.
What I would do is:
public static int maxOfArray(int[] a) {
int max = a[0];
for (int i : a)
if (max < i)
max = i;
return max;
}
public static int findMaxTheHardWay(int[] array) {
for (int length = array.length; length > 1; length = (length + 1) / 2) {
for (int i = 0; i < length / 2; i++) {
if (array[i] < array[length - i - 1])
array[i] = array[length - i - 1]; // don't need to swap.
}
}
return array[0];
}
public static void main(String... args) {
Random rand = new Random(1);
for (int i = 1; i <= 1000; i++) {
int[] a = new int[i];
for (int j = 0; j < i; j++) a[j] = rand.nextInt();
int max = maxOfArray(a);
int max2 = findMaxTheHardWay(a);
if (max != max2)
throw new AssertionError(i + ": " + max + " != " + max2);
}
}
This is rather a crazy way to solve the problem, but I'll play along.
The problem is in the inner loop.
You start out with i = 0 and k = length - 1.
If a[i] > a[k] you swap them.
...
You end up with k = 0 and i = length - 1
If a[i] > a[k] you swap them.
If you look at that carefully you will notice that if we swapped the elements in the first swap, we will also swap them in the last swap; i.e. we will UNDO the effects of the first swap. And the same applies pair-wise through the entire array slice.
See?
What you need to do is to stop the inner loop half way ... and then take account of the case where length is odd.
By the way, the reason I called this "rather crazy", because the obvious and simple way is much faster: O(N) versus O(NlogN)
int a[] = {1,7,3};
List<Integer> list = Arrays.asList(a);
Integer largest = Collections.max(list);
This will give you Largest number in Array.
Here is a solution that fits the specifications that you want (unlike many other here, humm, humm):
final Integer[] input = {1, 2, 6, 32, 4, 44 ,12, 42, 3, 7, 17, 22, 57, 23, 102, 103 };
int half = (input.length / 2);
int mod = input.length % 2;
while (half >= 0) {
for (int i = 0, j = (half * 2) + mod - 1; i <= half && j >= half; i++, j--) {
if (input[i] < input[j]) {
final int tmp = input[i];
input[i] = input[j];
input[j] = tmp;
}
}
if (half == 0) break;
half = half / 2;
mod = half % 2;
}
//Here, input[0] = the biggest number in the original input.
Edit: Added mod, so it works if the last element is the largest..
I think your code is working, you just have to ceil the length / 2 in case of odd array but my tests return proper result:
package org.devince.largestinteger;
import java.util.NoSuchElementException;
public class LargestInteger {
final static int[] input = {1, 2, 6, 32, 4, 44 ,12, 42, 3, 7, 17, 22, 57, 23, 102, 103 };
// final static int[] input = { 8, 1, 5, 4, 9, 4, 3, 7, 2 };
// final static int[] input = {1,3,7};
/**
* #param args
*/
public static void main(String[] args) {
System.out.println(String.valueOf(maxOfArray(input)));
}
public static int maxOfArray(int[] a)
{
int length = a.length;
if(length<1)
throw new NoSuchElementException("Not at least one integer in array");
while (length > 1)
{
int k = length;
for(int i = 0; i < length; i++)
{
k--;
if(a[i]>a[k])
{
int j = a[i];
a[i] = a[k];
a[k] = j;
}
}
length = (int) Math.ceil(length / 2f);
}
return a[0];
}
}
Why not just store the first value of the array to a variable max.
After that just loop through the array starting from second position till the last ,
in the loop just check if the current value is greater than max or not.If it is greater just assign max that value.
Return max and you have the largest number.
public int FindLargest()
{
int[] num = { 1, 2, 5, 12, 13, 56, 16, 4 };
int max = num[0];
for (int i = 1; i <num.length; i++)
{
if (num[i] > max)
{
max = num[i];
}
}
return max;
}
As the same u can approach like also,
int length = a.length;
while (length > 1)
{
int k = length;
for(int i = 0; i < length; i++)
{
for(int y = k-1; y >= i; y--)
{
if(a[i]<a[y])
{
int j = a[i];
a[i] = a[y];
a[y] = j;
}
}
}
length /=2;
}
final int validSampleRates[] = new int[]{
5644800, 2822400, 352800, 192000, 176400, 96000,
88200, 50400, 50000, 4800,47250, 44100, 44056, 37800, 32000, 22050, 16000, 11025, 4800, 8000};
ArrayList <Integer> YourArray = new ArrayList <Integer> ():
for (int smaple : validSampleRates){
YourArray.add(smaple);
}
Integer largest = Collections.max(YourArray);
System.out.println("Largest " + String.valueOf(largest));
The best way is to use Array that extends List Collection as ArrayList