Find longest subarray whose sum divisible by 3 with O(N) Complexity - java

i have big question here , if you can see below the code you will see code with O(N) complexity. im only try to decrease it to O(N^2),
Im treid to do it with O(N) but without any secces .
private static int f (int[]a, int low, int high)
{
int res = 0;
for (int i=low; i<=high; i++)
res += a[i];
return res;
}
public static int what (int []a)
{
int temp = 0;
for (int i=0; i<a.length; i++)
{
for (int j=i; j<a.length; j++)
{
int c = f(a, i, j);
if (c%3 == 0)
{
if (j-i+1 > temp)
temp = j-i+1;
}
}
}
return temp;
}

couple of exemple :
int[] a={1,2,4,1}; output : 2 ==> if you can see (1+2= 3 ) ,(2+4=6) so those is %3=0 ==> beacuse that the number is 2 beacuse is two subarray that giving me %3 to be =0.
int[] a={3,4,4,2}; output : 2
int[] a={3,3,3,3,0,1}; output : 5
int[] a={3,2,7,6,6,1}; output : 5

Related

I don't know why my code is giving wrong answer

Given an array A of 0s and 1s, we may change up to K values from 0 to 1.
Return the length of the longest (contiguous) subarray that contains only 1s.
Example 1:
Input: A = [1,1,1,0,0,0,1,1,1,1,0], K = 2
Output: 6
Explanation:
[1,1,1,0,0,1,1,1,1,1,1]
Bolded numbers were flipped from 0 to 1. The longest subarray is underlined.
Example 2:
Input: A = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
Output: 10
Explanation:
[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
Bolded numbers were flipped from 0 to 1. The longest subarray is underlined.
Note:
1 <= A.length <= 20000
0 <= K <= A.length
A[i] is 0 or 1
https://leetcode.com/problems/max-consecutive-ones-iii/
This is the question link. On the first test case, I am getting output 9 but it should be 6. I can't figure out where it is going wrong?
public static int f(int arr[],int n,int tar)
{
int st=0,maxc=0,maxf=0;
//tar=tar+1;
for(int i=0;i<n;i++)
{
int se=i-st-maxc;
if(arr[i]==1)
maxc++;
while(i-st-maxc>tar)
{
maxf=Math.max(maxf, i-st);
st++;
}
}
return maxf+1;
}
public static void main(String[] args)
{
Scanner p=new Scanner(System.in);
int n,target;
n=p.nextInt();
target=p.nextInt();
int arr[]=new int[n];
for(int i=0;i<n;i++)
{
arr[i]=p.nextInt();
}
int ans=f(arr,n,target);
System.out.println(ans);
}
You do not need to provide the size of the array because you can get the size from the array.
If you use better variable names, the readability of the code will be better.
Also, you can use if statements in order to check changed values instead of counting.
This is example of the solution:
public static int longestOnes(int[] A, int K) {
var maxCount = 0;
for (int i = 0; i < A.length; i++) {
var count = 0;
var k = 0;
for (int j = i; j < A.length; j++) {
if (A[j] == 1) {
count++;
}
if (A[j] == 0) {
if (k >= K) {
if (count > maxCount) {
maxCount = count;
}
break;
}
count++;
k++;
}
}
}
return maxCount;
}

Shift array to the left

so I'm trying to shift an array to the left, eg, if the original array was '1,2,3,4', the transformed one would become '2,3,4,1', this is what i have so far and i keep getting an missing return statement error, how would i go about fixing it?
public int shift ( int [] d){
for(int from =1; from <= d.length-1; from++)
d[from-1]= d[from];
System.out.println ("d[from]"+",d[0]");
}
Your logic is right but you just need some modify in your code.
int data[]={1,2,3,4};
shift(data);
//print out Shifted Array
for(int n : data){
System.out.println(n);
}
public void shift(int[] d){
int f=d[0]; // Store first index
int from=1;
for(;from<d.length;from++){
d[from-1]=d[from];
}
d[from-1]=f; //set first index to the last index
}
You don't need to return any data because java pass the reference of
the object not value.
public static void shift(int[] arr, int offs) {
// e.g. arr = 1,2,3,4,5,6,7,8,9; offs = 3
offs %= arr.length;
offs = offs < 0 ? arr.length + offs : offs;
if (offs > 0) {
// reverse whole array (arr = 9,8,7,6,5,4,3,2,1)
for (int i = 0, j = arr.length - 1; i < j; i++, j--)
swap(arr, i, j);
// reverse left part (arr = 7,8,9,6,5,4,3,2,1)
for (int i = 0, j = offs - 1; i < j; i++, j--)
swap(arr, i, j);
// reverse right part (arr = 7,8,9,1,2,3,4,5,6)
for (int i = offs, j = arr.length - 1; i < j; i++, j--)
swap(arr, i, j);
}
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
Using Collections.rotate:
public List<Integer> shift(int [] d) {
List<Integer> intList = new ArrayList<Integer>();
for (int index = 0; index < d.length; index++) {
intList.add(d[index]);
}
Collections.rotate(intList, -1);
return intList;
}
The following code is in PHP to shift the array to left based on the given transformation number.
<?php
$a = [2,3,4,5,6];
$k1 = 2;
$k2 = 10;
function leftshift($ar, $n , $k){
$mod = $k % $n;
for ($i = 0; $i < $n; $i++) {
echo ($ar[($mod + $i) % $n]) , " ";
echo "\n";
}
}
$n = count($a);
leftshift($a,$n,$k1);
leftshift($a,$n,$k2);
?>
public int shift (int[] d) {
for(int from =1; from <= d.length-1; from++)
d[from-1]= d[from];
System.out.println ("d[from]"+",d[0]");
return d.length=0?0:d[0];
}
Note that an array maybe of size zero, and you may get "index out of bounds exception".

Sorting an array with heap sort

I was working my Algorithm's midterm review and I tried to implement all the pseudo codes by Java in order to have a better understanding of algorithm. But on the heap sort part, there was something wrong with my code. My input array is
{10,16,4,10,14,7,9,3,2,8,1}
and the first element just represents the number of elements that I would like to sort. In other words, the elements needed to be sorted start from index 1.
My output of build max-heap is :
16 14 10 8 7 9 3 2 4 1
And my output of heap sort is :
1 3 2 4 7 8 9 10 14 16
It seemed my build-max-heap part worked well but I couldn't find bugs in heap-sort part, either.
public class Midterm{
public static void main(String[] args){
int[] C = {10,16,4,10,14,7,9,3,2,8,1};
/*for convenience, the first element in array C represent the
number of elements needed to be heapified;
*/
Midterm heap = new Midterm();
int n = C.length - 1;
for (int i = (n / 2); i > 0; i--){
heap.maxHeapify(C, i, n);
}
int index = 1;
while(index <= n){
System.out.print(C[index] + " ");
index++;
}
System.out.println();
Midterm heap2 = new Midterm();
heap2.heapSort(C);
int index2 = 1;
while(index2 <= n){
System.out.print(C[index2] + " ");
index2++;
}
System.out.println();
}
public void heapSort(int[] A){
int n = A.length - 1;
for (int i = n; i >= 2; i--){
exchange(A, 1, i);
maxHeapify(A, 1, i - 1);
}
}
public void maxHeapify(int[] A, int i, int n){
int left = 2 *i, right = 2 * i + 1;
int largest;
if (left < n && A[left] > A[i]){
largest = left;
}else{
largest = i;
}
if (right < n && A[right] > A[largest]){
largest = right;
}
if (largest != i){
exchange(A, i, largest);
maxHeapify(A, largest,n);
}
}
private void exchange(int[] A, int i , int j){
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
There are 2 mistakes in your code:
1. The for loop for the heapsort goes from last element to first element, so
for (int i = n; i >= 2; i--){
should be:
for (int i = n; i >= 1; i--){
because the indices start from 0.
2. After performing a exchange(A, 1, i), the right call should be:
maxHeapify(A, 1, i)
check the below code.
public class HeapSort
{
public void sort(int arr[])
{
int n = arr.length;
// Build heap (rearrange array)
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// One by one extract an element from heap
for (int i=n-1; i>=0; i--)
{
// Move current root to end
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
// call max heapify on the reduced heap
heapify(arr, i, 0);
}
}
// To heapify a subtree rooted with node i which is
// an index in arr[]. n is size of heap
void heapify(int arr[], int n, int i)
{
int largest = i; // Initialize largest as root
int l = 2*i + 1; // left = 2*i + 1
int r = 2*i + 2; // right = 2*i + 2
// If left child is larger than root
if (l < n && arr[l] > arr[largest])
largest = l;
// If right child is larger than largest so far
if (r < n && arr[r] > arr[largest])
largest = r;
// If largest is not root
if (largest != i)
{
int swap = arr[i];
arr[i] = arr[largest];
arr[largest] = swap;
// Recursively heapify the affected sub-tree
heapify(arr, n, largest);
}
}
/* A utility function to print array of size n */
static void printArray(int arr[])
{
int n = arr.length;
for (int i=0; i<n; ++i)
System.out.print(arr[i]+" ");
System.out.println();
}
// Driver program
public static void main(String args[])
{
int arr[] = {12, 11, 13, 5, 6, 7};
int n = arr.length;
HeapSort ob = new HeapSort();
ob.sort(arr);
System.out.println("Sorted array is");
printArray(arr);
}
}

Best implementation to remove duplicates JAVA array [duplicate]

This question already has answers here:
Java Remove Duplicates from an Array?
(10 answers)
Closed 8 years ago.
Found this solution to make this method:
int[] withoutDuplicates(int[] a){
int n = a.length;
if (n < 2) {
return a;
}
for (int i = 0; i < n-1; i++) {
for (int j = i+1; j < n; j++) {
if (a[j] == a[i]) {
--n;
System.arraycopy(a, j+1, a, j, n-j);
--j;
}//end if
} //end for
}//end for
int[] aa = new int[n];
System.arraycopy(a, 0, aa, 0, n);
return aa;
}//end method
I do not understand why it is using an array of length n. Shouldn't it be of size n minus the number of duplicates erased?
Is this the most optimal way of implementing the method? or is there any java resource I could use?
I am, by nature, lazy. I would do this:
-- EDIT --
private int[] withoutDuplicates(int[] a){
Set<Integer> set = new LinkedHashSet<Integer>();
for (int x : a) {
set.add(x);
}
int[] newArray = new int[set.size()];
int ii = 0;
for (Integer x : set) {
newArray[ii++] = x;
}
return newArray;
}
Here is an algorithm for removing duplicates and maintaining the relative order.
Time: O(n)
Space: O(n)
public static void dupCheck(int [] a){
int j=0;
HashMap<Integer,Boolean> map = new HashMap<Integer,Boolean>();
int [] b = new int [a.length];
for(int i=0;i<a.length;i++){
if(!map.containsKey(a[i])){
map.put(a[i],true);
b[j++]=a[i];
}
}
for(int i=0;i<j;i++)
System.out.print(b[i]+" ");
}

Recursion - Combination with in array with no repetition in Java

So I know how to get the size of a combination - factorial of the size of the array (in my case) over the size of the subset of that array wanted. The issue I'm having is getting the combinations. I've read through most of the questions so far here on stackoverflow and have come up with nothing. I think the issue I'm finding is that I want to add together the elements in the combitorial subsets created. All together this should be done recursively
So to clarify:
int[] array = {1,2,3,4,5};
the subset would be the size of say 2 and combinations would be
{1,2},{1,3},{1,4},{1,5},{2,3},{2,4},{2,5},{3,4},{3,5},{4,5}
from this data I want to see if the subset say... equals 6, then the answers would be:
{1,5} and {2,4} leaving me with an array of {1,5,2,4}
so far I have this:
public static int[] subset(int[] array, int n, int sum){
// n = size of subsets
// sum = what the sum of the ints in the subsets should be
int count = 0; // used to count values in array later
int[] temp = new temp[array.length]; // will be array returned
if(array.length < n){
return false;
}
for (int i = 1; i < array.length; i++) {
for (int j = 0; j < n; j++) {
int[] subset = new int[n];
System.arraycopy(array, 1, temp, 0, array.length - 1); // should be array moved forward to get new combinations
**// unable to figure how how to compute subsets of the size using recursion so far have something along these lines**
subset[i] = array[i];
subset[i+1] = array[i+1];
for (int k = 0; k < n; k++ ) {
count += subset[k];
}
**end of what I had **
if (j == n && count == sum) {
temp[i] = array[i];
temp[i+1] = array[i+1];
}
}
} subset(temp, n, goal);
return temp;
}
How should I go about computing the possible combinations of subsets available?
I hope you will love me. Only thing you have to do is to merge results in one array, but it checks all possibilities (try to run the program and look at output) :) :
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5};
int n = 2;
subset(array, n, 6, 0, new int[n], 0);
}
public static int[] subset(int[] array, int n, int sum, int count, int[] subarray, int pos) {
subarray[count] = array[pos];
count++;
//If I have enough numbers in my subarray, I can check, if it is equal to my sum
if (count == n) {
//If it is equal, I found subarray I was looking for
if (addArrayInt(subarray) == sum) {
return subarray;
} else {
return null;
}
}
for (int i = pos + 1; i < array.length; i++) {
int[] res = subset(array, n, sum, count, subarray.clone(), i);
if (res != null) {
//Good result returned, so I print it, here you should merge it
System.out.println(Arrays.toString(res));
}
}
if ((count == 1) && (pos < array.length - 1)) {
subset(array, n, sum, 0, new int[n], pos + 1);
}
//Here you should return your merged result, if you find any or null, if you do not
return null;
}
public static int addArrayInt(int[] array) {
int res = 0;
for (int i = 0; i < array.length; i++) {
res += array[i];
}
return res;
}
You should think about how this problem would be done with loops.
for (int i = 0; i < array.length - 1; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] + array[j] == sum) {
//Add the values to the array
}
}
}
Simply convert this to a recursive code.
The best way I can think to do this would be to have each recursive call run on a subset of the original array. Note that you don't need to create a new array to do this as you are doing in your code example. Just have a reference in each call to the new index in the array. So your constructor might look like this:
public static int[] subset(int[] array, int ind, int sum)
where array is the array, ind is the new starting index and sum is the sum you are trying to find

Categories

Resources