Finding a sub array in an array in Java - java

I am trying to write a program using two methods that determines if a sub array is located within an array. subArray() is supposed to receive two arrays and return the index of the start of the sub array within the array. If the sub array is not located in the array it returns -1. subArray() then calls subArrayAppearsAt() and passes in the two arrays and a location. subArrayAppearsAt() is supposed to return true if the sub array is located in the array starting at the location passed in, false otherwise.
Currently if I pass in array {1,2,3} and sub array {2,3}, it returns 2 as the starting position but it should return 1.
If I pass in array {1,2,3,4,5} and sub array {4}, it returns -1, but it should return 3.
Does anyone see why this might be happening?
public static int subArray(int [ ] array, int [ ] subArray )
{
boolean result=true;
int subArrayLength = subArray.length;
if (subArrayLength == 0) {
return -1;
}
int limit = array.length - subArrayLength;
int i;
for ( i = 0; i <= limit; i++)
result = subArrayAppearsAt(array, subArray, i );
if (result==true)
return i;
else
return -1;
}
public static boolean subArrayAppearsAt(int[] largeArray, int[] subArray, int i) {
{
if (subArray[0] == largeArray[i])
{
boolean subArrayFound = true;
for (int j = 1; j < subArray.length; j++)
{
if (subArray[j] != largeArray[i+j])
{
subArrayFound = false;
j=subArray.length;
}
/* Sub array found - return its index */
if (subArrayFound==true)
{
return true;
}
}
}
}
/* Return default value */
return false;
}

Look at this part
for ( i = 0; i <= limit; i++)
result = subArrayAppearsAt(array, subArray, i );
it sets result every time it goes through the loop. If you test if {4} is conatined in {1, 2, 3, 4, 5} it will set result to the return value of subArrayAppearsAt(array, subArray, 4); which will return false
So for that problem you could do something like
for ( i = 0; i <= limit; i++) {
result = subArrayAppearsAt(array, subArray, i );
if (result==true)
return i;
}
return -1;
The other problem is, that i will be incremented after it goes into the for-loop the last time, and then you return that value. That problem should be solved with my code solution too.
I didn't test my solution but it should work ;)
EDIT
Sorry that wasn't all correct. Your subArrayAppearsAt() returns true too early. Edit your subArrayAppearsAt() function to this and it should work
public static boolean subArrayAppearsAt(int[] largeArray, int[] subArray, int i)
{
if (subArray[0] == largeArray[i])
{
for (int j = 1; j < subArray.length; j++)
{
if (subArray[j] != largeArray[i+j])
{
return false;
}
}
return true;
}
return false;
}

The problem is that if you want to know the start position you should put the if that checks the result inside de loop
public static int subArray(int [ ] array, int [ ] subArray )
{
boolean result=true;
int subArrayLength = subArray.length;
if (subArrayLength == 0) {
return -1;
}
int limit = array.length - subArrayLength;
int i;
for ( i = 0; i <= limit; i++){
result = subArrayAppearsAt(array, subArray, i );
if (result==true)
return i;
}
return -1;
}

public static void main(String[] args) {
int[] first = {1,2,4,5,3,2,1,3,4,5,6,33,432,21,5};
int[] second = {2,1};
System.out.println(findpos(first, second));
}
private static int findpos(int[] a, int[] b){
for(int i=0; i<a.length; i++){
if(a[i]!=b[0]){
continue;
}
if(a.length - i < b.length) return -1;
int itemp = i;
boolean found = true;
for(int j=0; j<b.length; j++){
if(itemp < a.length && a[itemp]!=b[j]){
found = false;
}
itemp++;
}
if(found){
return i;
}
}
return -1;
}

Related

How to count the number of subarrays within a bigger array using recursion

How can you get a subarray from a bigger array recursively, and without using copyOfRange?
For example if int[] a = {1,2,1,3,1,2,1,1,2}, and int[] b = {1,2}, the correct answer is 3.
This is the only recursive call I have, but I'm not sure what to do beyond this.
I know the base case should be if(a.length < b.length), but I don't understand how to count the occurrences.
The function returns return numSubstring(a,b,low, mid-1) + numSubstring(a,b, mid+1,high);
public static int countSubs(int [] data, int [] sub) {
int cnt = 0;
if (data.length < sub.length) {
return cnt;
}
boolean found = true;
for (int i = 0; i < sub.length; i++) {
if (data[i] != sub[i]) {
found = false;
break;
}
}
if (found) {
cnt++;
}
cnt += countSubs(Arrays.copyOfRange(data, 1, data.length), sub);
return cnt;
}

26. Remove Duplicates from Sorted Array - Java

Question : Given a sorted array nums, remove the duplicates in-place such that each element appears only once and returns the new length.
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int i = 0;
for (int j = 1; j < nums.length; j++) {
if (nums[j] != nums[i]) {
i++;
nums[i] = nums[j];
}
}
return i + 1;
}
What exactly does the return statement do here. What does return i + 1 mean here ?
The return i + 1 is returning how many unique integers are there. I believe this is a Leetcode problem, and since its in place, the int[] is passed in by reference, Leetcode wants to know how many numbers to check (you're supposed to put the unique numbers in the first i + 1 spots).
If you look at the question, it says:
Which means that you return the length of the array.
So, if you have the array [1,1,2,3,4,4], you would turn that into [1,2,3,4,...], where the ... is the rest of the array. However, you return 4 because the length of the new array should be 4.
Hope this clears things up for you!
Your question has been already answered here; in addition to that, we can also start from zero and remove the first if statement:
Test with a b.java file:
import java.util.*;
class Solution {
public static final int removeDuplicates(
final int[] nums
) {
int i = 0;
for (int num : nums)
if (i == 0 || num > nums[i - 1]) {
nums[i++] = num;
}
return i;
}
}
class b {
public static void main(String[] args) {
System.out.println(new Solution().removeDuplicates(new int[] { 1, 1, 2}));
System.out.println(new Solution().removeDuplicates(new int[] { 0, 0, 1, 1, 1, 2, 2, 3, 3, 4}));
}
}
prints
2
5
I tried in this easy way. Here Time complexity is O(n) and space
complexity: O(1).
static int removeDuplicates(int[] nums){
if(nums.length == 0) {
return 0;
}
int value = nums[0];
int lastIndex = 0;
int count = 1;
for (int i = 1; i < nums.length; i++) {
if(nums[i] > value) {
value = nums[i];
lastIndex = lastIndex+1;
nums[lastIndex] = value;
count++;
}
}
return count;
}
class Solution {
public int removeDuplicates(int[] nums) {
int n = nums.length;
if (n == 0 || n == 1)
return n;
int j = 0;
for (int i=0; i<n-1; i++)
if (nums[i]!= nums[i+1])
nums[j++] = nums[i];
nums[j++]=nums[n-1];
return j;
}
}
public class RemoveDuplicateSortedArray {
//Remove Duplicates from Sorted Array
public static void main(String[] args) {
int[] intArray = new int[]{0, 0, 1, 1, 1, 2, 2, 3, 3, 4};
int count = extracted(intArray);
for (int i = 0; i < count; i++) {
System.out.println(intArray[i]);
}
}
private static int extracted(int[] intArray) {
int size = intArray.length;
int count = 1;
if (size == 1) {
return 1;
} else if (size == 2) {
if (intArray[0] == intArray[1]) {
return 1;
} else {
return 2;
}
} else {
for (int i = 0, j = i + 1; j < size; j++) {
if (intArray[i] < intArray[j]) {
i++;
intArray[i] = intArray[j];
count++;
}
}
return count;
}
}
}

Random Sort does not terminate

Assuming isAscSorted functions as expected (tested)
I am doing something silly here which is why random swap never sorts the array - because it is only ever doing 1 swap each time on different arrays?
My test case is
int[] values1 = new int[] { 50, 10, 20, 4, 5, 1, 5 };
Hints?
public static boolean isAscSorted (int[] arr){
for (int i=0; i<arr.length-1; i++){
if (arr[i]> arr[i+1]){
return false;
}
}
return true;
}
public static boolean swap(int[]a,int i,int j)
{
if (i == j){
return false;
}
int temp=a[i];
a[i]= a[j];
a[j]=temp;
return true;
}
static int randomSort(int[] values) {
//Ok Array is empty or null
if( values == null || values.length==0){
return 0;
}
boolean isSorted = false;
int steps = 0;
Random r = new Random();
int limit = values.length-1; //SOL: should be int limit = values.length;
while (!isAscSorted(values)){
//choose 2 random positions
int r1 = r.nextInt(limit);
int r2 = r.nextInt(limit);
//swap returns true if successful
boolean swapRes = swap(values, r1,r2);
//increment steps counter
if (swapRes)
steps++;
}
return steps;
}
The bug was with the use of Random.
I had indicated int limit = values.length-1;
This meant the last array position was never swapped and so the array could never be sorted (unless the 2nd and last numbers were identical and maximal for example).

Finding non duplicate element in an array

I am stuck in the following program:
I have an input integer array which has only one non duplicate number, say {1,1,3,2,3}. The output should show the non duplicate element i.e. 2.
So far I did the following:
public class Solution {
public int singleNumber(int[] arr){
int size = arr.length;
int temp = 0;
int result = 0;
boolean flag = true;
int[] arr1 = new int[size];
for(int i=0;i<size;i++){
temp = arr[i];
for(int j=0;j<size;j++){
if(temp == arr[j]){
if(i != j)
//System.out.println("Match found for "+temp);
flag = false;
break;
}
}
}
return result;
}
public static void main(String[] args) {
int[] a = {1,1,3,2,3};
Solution sol = new Solution();
System.out.println("SINGLE NUMBER : "+sol.singleNumber(a));
}
}
Restricting the solution in array is preferable. Avoid using collections,maps.
public class NonRepeatingElement {
public static void main(String[] args) {
int result =0;
int []arr={3,4,5,3,4,5,6};
for(int i:arr)
{
result ^=i;
}
System.out.println("Result is "+result);
}
}
Since this is almost certainly a learning exercise, and because you are very close to completing it right, here are the things that you need to change to make it work:
Move the declaration of flag inside the outer loop - the flag needs to be set to true every iteration of the outer loop, and it is not used anywhere outside the outer loop.
Check the flag when the inner loop completes - if the flag remains true, you have found a unique number; return it.
From Above here is the none duplicated example in Apple swift 2.0
func noneDuplicated(){
let arr = [1,4,3,7,3]
let size = arr.count
var temp = 0
for i in 0..<size{
var flag = true
temp = arr[i]
for j in 0..<size{
if(temp == arr[j]){
if(i != j){
flag = false
break
}
}
}
if(flag == true){
print(temp + " ,")
}
}
}
// output : 1 , 4 ,7
// this will print each none duplicated
/// for duplicate array
static void duplicateItem(int[] a){
/*
You can sort the array before you compare
*/
int temp =0;
for(int i=0; i<a.length;i++){
for(int j=0; j<a.length;j++){
if(a[i]<a[j]){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
int count=0;
for(int j=0;j<a.length;j++) {
for(int k =j+1;k<a.length;k++) {
if(a[j] == a[k]) {
count++;
}
}
if(count==1){
System.out.println(a[j]);
}
count = 0;
}
}
/*
for array of non duplicate elements in array just change int k=j+1; to int k = 0; in for loop
*/
static void NonDuplicateItem(int[] a){
/*
You can sort the array before you compare
*/
int temp =0;
for(int i=0; i<a.length;i++){
for(int j=0; j<a.length;j++){
if(a[i]<a[j]){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
int count=0;
for(int j=0;j<a.length;j++) {
for(int k =0 ;k<a.length;k++) {
if(a[j] == a[k]) {
count++;
}
}
if(count==1){
System.out.println(a[j]);
}
count = 0;
}
}
public class DuplicateItem {
public static void main (String []args){
int[] a = {1,1,1,2,2,3,6,5,3,6,7,8};
duplicateItem(a);
NonDuplicateItem(a);
}
/// for first non repeating element in array ///
static void FirstNonDuplicateItem(int[] a){
/*
You can sort the array before you compare
*/
int temp =0;
for(int i=0; i<a.length;i++){
for(int j=0; j<a.length;j++){
if(a[i]<a[j]){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
int count=0;
for(int j=0;j<a.length;j++) {
//int k;
for(int k =0; k<a.length;k++) {
if(a[j] == a[k]) {
count++;
}
}
if(count==1){
System.out.println(a[j]);
break;
}
count = 0;
}
}
public class NonDuplicateItem {
public static void main (String []args){
int[] a = {1,1,1,2,2,3,6,5,3,6,7,8};
FirstNonDuplicateItem(a);
}
I have a unique answer, it basically takes the current number that you have in the outer for loop for the array and times it by itself (basically the number to the power of 2). Then it goes through and every time it sees the number isn't equal to double itself test if its at the end of the array for the inner for loop, it is then a unique number, where as if it ever find a number equal to itself it then skips to the end of the inner for loop since we already know after one the number is not unique.
public class Solution {
public int singleNumber(int[] arr){
int size = arr.length;
int temp = 0;
int result = 0;
int temp2 = 0;
int temp3 = 0;
boolean flag = true;
int[] arr1 = new int[size];
for(int i=0;i<size;i++){
temp = arr[i];
temp2 = temp*temp;
for(int j=0;j<size;j++){
temp3 = temp*arr[j];
if(temp2==temp3 && i!=j)
j=arr.length
if(temp2 != temp3 && j==arr.length){
//System.out.println("Match found for "+temp);
flag = false;
result = temp;
break;
}
}
}
return result;
}
public static void main(String[] args) {
int[] a = {1,1,3,2,3};
Solution sol = new Solution();
System.out.println("SINGLE NUMBER : "+sol.singleNumber(a));
}
}
not tested but should work
public class Solution {
public int singleNumber(int[] arr){
int size = arr.length;
int temp = 0;
int result = 0;
boolean flag = true;
int[] arr1 = new int[size];
for(int i=0;i<size;i++){
temp = arr[i];
int count=0;
for(int j=0;j<size;j++){
if(temp == arr[j]){
count++;
}
}
if (count==1){
result=temp;
break;
}
}
return result;
}
Try:
public class Answer{
public static void main(String[] args) {
int[] a = {1,1,3,2,3};
int[] b =new int[a.length];
//instead of a.length initialize it to maximum element value in a; to avoid
//ArrayIndexOutOfBoundsException
for(int i=0;i<a.length;i++){
int x=a[i];
b[x]++;
}
for(int i=0;i<b.length;i++){
if(b[i]==1){
System.out.println(i); // outputs 2
break;
}
}
}
}
PS: I'm really new to java i usually code in C.
Thanks #dasblinkenlight...followed your method
public class Solution {
public int singleNumber(int[] arr){
int size = arr.length;
int temp = 0;
int result = 0;
int[] arr1 = new int[size];
for(int i=0;i<size;i++){
boolean flag = true;
temp = arr[i];
for(int j=0;j<size;j++){
if(temp == arr[j]){
if(i != j){
// System.out.println("Match found for "+temp);
flag = false;
break;
}
}
}
if(flag == true)
result = temp;
}
return result;
}
public static void main(String[] args) {
int[] a = {1,1,3,2,3};
Solution sol = new Solution();
System.out.println("SINGLE NUMBER : "+sol.singleNumber(a));
}
}
One disastrous mistake was not enclosing the content of if(i != j) inside braces. Thanks all for your answers.
If you are coding for learning then you can solve it with still more efficiently.
Sort the given array using merge sort of Quick Sort.
Running time will be nlogn.
The idea is to use Binary Search.
Till required element found All elements have first occurrence at even index (0, 2, ..) and next occurrence at odd index (1, 3, …).
After the required element have first occurrence at odd index and next occurrence at even index.
Using above observation you can solve :
a) Find the middle index, say ‘mid’.
b) If ‘mid’ is even, then compare arr[mid] and arr[mid + 1]. If both are same, then the required element after ‘mid’ else before mid.
c) If ‘mid’ is odd, then compare arr[mid] and arr[mid – 1]. If both are same, then the required element after ‘mid’ else before mid.
Another simple way to do so..
public static void main(String[] art) {
int a[] = { 11, 2, 3, 1,1, 6, 2, 5, 8, 3, 2, 11, 8, 4, 6 ,5};
Arrays.sort(a);
System.out.println(Arrays.toString(a));
for (int j = 0; j < a.length; j++) {
if(j==0) {
if(a[j]!=a[j+1]) {
System.out.println("The unique number is :"+a[j]);
}
}else
if(j==a.length-1) {
if(a[j]!=a[j-1]) {
System.out.println("The unique number is :"+a[j]);
}
}else
if(a[j]!=a[j+1] && a[j]!=a[j-1]) {
System.out.println("The unique number is :"+a[j]);
}
}
}
Happy Coding..
Using multiple loops the time complexity is O(n^2), So the effective way to resolve this using HashMap which in the time complexity of O(n). Please find my answer below,
`public static int nonRepeatedNumber(int[] A) {
Map<Integer, Integer> countMap = new HashMap<>();
int result = -1;
for (int i : A) {
if (!countMap.containsKey(i)) {
countMap.put(i, 1);
} else {
countMap.put(i, countMap.get(i) + 1);
}
}
Optional<Entry<Integer, Integer>> optionalEntry = countMap.entrySet().stream()
.filter(e -> e.getValue() == 1).findFirst();
return optionalEntry.isPresent() ? optionalEntry.get().getKey() : -1;
}
}`

Recursive method to find max value

maxRec() is meant to calculate the maximum value within an array using a helper
method maximize(). When this code executes, it always seems to return zero, however
it will print out the correct value. When using a debugger, I noticed that
the maxRec() method will get the right return value but wont return it; instead it sets it back to zero and moves up to the else statement.I would be grateful for any suggestions that could help fix this.
public int maxRec(int[] v) {
int maxValue = 0;
int[] tempArray = maximize(v);
boolean executeCode = true;
if (tempArray.length == 1) {
maxValue = tempArray[0];
executeCode = false;
System.out.println(maxValue);
} else if (executeCode == true && tempArray.length != 1) {
maxRec(tempArray);
}
return maxValue;
}
public int[] maximize(int[] v) {
int count = 0;
int secondCount = 0;
for (int i = 0; i < v.length; i++) {
if (v[i] > v[0]) {
count++;
}
}
int[] newArray;
newArray = new int[count];
for (int i = 0; i < v.length; i++) {
if (v[i] > v[0]) {
newArray[secondCount] = v[i];
secondCount++;
}
}
return newArray;
}
Code should be changed like this.
public int maxRec(int[] v)
{
int maxValue=0;
int[] tempArray = maximize(v);
boolean executeCode = true;
if(tempArray.length==1)
{
maxValue=tempArray[0];
executeCode=false;
}
else if(executeCode==true && tempArray.length!=1 && tempArray.length > 0)
{
maxValue = maxRec(tempArray);
}
return maxValue;
}
public int[] maximize(int[] v)
{
int count=0;
int secondCount=0;
for(int i=0;i<v.length;i++)
{
if(v[i]>v[0])
{
count++;
}
}
int[] newArray;
newArray = new int[count];
if(count == 0)
{
newArray = new int[1];
newArray[0] = v[0];
return newArray;
}
for(int i=0;i<v.length;i++)
{
if(v[i]>v[0])
{
newArray[secondCount]=v[i];
secondCount++;
}
}
return newArray;
}
maximize returns an array of all values greater than the first item of the array.
To make a recursive function, one starts with the simplest case, the least work.
The rest one delegates to a clone of oneself, the recursive call.
public int maxRec(int[] v) {
if (v.length == 0) {
throw IllegalArgumentException();
}
int[] greaterThanFirst = maximize(v);
int maxValue = 0;
if (greaterThanFirst.length == 0) {
maxValue = v[0];
} else {
maxValue = maxRec(greaterThanFirst);
}
return maxValue;
}
First a sanity check, v not being empty.
If maximize did not yield a larger number, yield the first value, being the largest.
//-------------------------------------------------------------------
// 1. maxRec --> Computes the maximum item of MyList
//-------------------------------------------------------------------
/**
* The function computes the maximum item of m (-1 if m is empty).
* #param m: The MyList we want to compute its maximum item.
* #return: The maximum item of MyList
*/
public int maxRec(MyList<Integer> m){
int max = 0;
int res = 0;
int e0 = 0;
int e1 = 0;
// Scenarios Identification
int scenario = 0;
// Type 1. MyLyst is empty
if(m.length() == 0) {
scenario = 1;
}else {
scenario = 2;
}
// Scenario Implementation
switch(scenario) {
// If MyLyst is empty
case 1:
res = -1;
break;
// If there is 1 or more elements
case 2:
// Old School
for(int i = 0; i <= m.length()-1; i++)
if(m.getElement(i) > max) {
max = m.getElement(i);
}
// Recursively
//1. Get and store first element of array
e0 = m.getElement(0);
//2. We remove the first element from MyList we just checked
m.removeElement(0);
//3. We recursively solve the smaller problem
e1 = maxRec(m);
//4. Compare and store results
if(e0 > e1) {
res = e0;
}
else {
res = e1;
}
//5. Return removed element back to the array
m.addElement(0, e0);
break;
}
//6.Display the process to see what's going on
System.out.println("My Way: "+ max);
System.out.println("Recursive Way: " + res);
//7. Return result
return res;
}

Categories

Resources