An array is a linear data structure in which elements are stored in contiguous memory locations.
As per problem statement, we have to find all the subarrays of a given array. Subarrays are part or a section of an array. When we talk about all subarrays of an array, we talk about the total number of combinations that can be made using all the elements of the array without repeating.
Let’s explore the article to see how it can be done by using Java programming language.
To Show you Some Instances
Instance-1
Suppose we have the below array
[10, 2, 3, -5, 99, 12, 0, -1]
The subarrays of this array would be
10 10 2 10 2 3 10 2 3 -5 10 2 3 -5 99 10 2 3 -5 99 12 10 2 3 -5 99 12 0 10 2 3 -5 99 12 0 -1 2 2 3 2 3 -5 2 3 -5 99 2 3 -5 99 12 2 3 -5 99 12 0 2 3 -5 99 12 0 -1 3 3 -5 3 -5 99 3 -5 99 12 3 -5 99 12 0 3 -5 99 12 0 -1 -5 -5 99 -5 99 12 -5 99 12 0 -5 99 12 0 -1 99 99 12 99 12 0 99 12 0 -1 12 12 0 12 0 -1 0 0 -1 -1
Instance-2
Suppose we have the below array
[55,10,29,74]
The subarrays of this array would be
55 55 10 55 10 29 55 10 29 74 10 10 29 10 29 74 29 29 74 74
Algorithm
Algorithm-1
-
Step 1 − After storing the array, run a for loop from 0 to n. This will mark our starting point of the main array.
-
Step 2 − Run another for loop that runs from the first iterator to the ending point of the main array.
-
Step 3 − Now run another loop that traverses the elements between both two iterators.
-
Step 4 − Print the elements in a sequential order.
Algorithm-2
-
Step 1 − After storing the array, check if we have reached the end, then go out of the function.
-
Step 2 − If the start index is greater than the end index, then call the function itself from 0 to end+1.
-
Step 3 − Else print the array elements between the indices inside a for loop, and call the function again from start+1 to end.
-
Step 4 − Exit.
Syntax
To get the length of an array (number of elements in that array), there is an inbuilt property of array i.e length
Below refers to the syntax of it −
array.length
where, ‘array’ refers to the array reference.
You can use Arrays.sort() method to sort the array in ascending order.
Arrays.sort(array_name);
Multiple Approaches
We have provided the solution in different approaches.
-
By Using for Loops
-
By Using Recursion
Let’s see the program along with its output one by one.
Approach-1: By Using for Loops
In this approach, we will use three for loops to find the subarrays of an array. The first loop to mark the start and the second to mark the end of the subarray, while the third prints the subarray.
Example
import java.io.*; public class Main { public static void main(String[] args) { // The array elements int arr[] = { 10, 2, 3, 99, 12, 0 }; System.out.println("The subarrays are-"); // For loop for start index for (int i = 0; i < arr.length; i++) // For loop for end index for (int j = i; j < arr.length; j++) { // For loop to print subarray elements for (int k = i; k <=j; k++) System.out.print(arr[k] + " "); System.out.println(""); } } }
Output
The subarrays are- 10 10 2 10 2 3 10 2 3 99 10 2 3 99 12 10 2 3 99 12 0 2 2 3 2 3 99 2 3 99 12 2 3 99 12 0 3 3 99 3 99 12 3 99 12 0 99 99 12 99 12 0 12 12 0 0
Approach-2: By Using Recursion
In this approach, we find all the subarrays but using recursion.
Example
import java.io.*; public class Main { //main method public static void main(String[] args) { // The array elements int arr[] = { 10, 2, 3}; System.out.println("The subarrays are-"); // Calling the recursive function printSubArrays(arr, 0, 0); } // Recursive FUnction to Find all the subarrays static void printSubArrays(int[] arr, int head, int tail) { // Exits the function if we have reached the end if (tail == arr.length) return; // Increases the first index and calls itself else if (head > tail) printSubArrays(arr, 0, tail + 1); // Print the subarray and then increases the first element index else { for (int i = head; i < tail; i++) System.out.print(arr[i] + " "); System.out.println(arr[tail]); printSubArrays(arr, head + 1, tail); } return; } }
Output
The subarrays are- 10 10 2 2 10 2 3 2 3 3
In this article, we explored how to find all the subarrays of a given array by using Java programming language.
Это базовый алгоритм, но он в большинстве ситуациях будет работать за O(N) операций. Понять это можно через просмотр условия внутреннего цикла, до второй итерации будет очень редко доходить, а тем более до третий и далее.
Худший случай достигается при ситуации base = [1,1,1,1,1,1,1,1,1] find = [1,1,1,1]
. Но вы думаете что есть алгоритм, который в такой ситуации сработает быстрее? Ну может быть и есть, но подобные ‘долгие’ ситуации очень редки, если брать все возможности ситуаций. И возможно даже если асимптотически такой алгоритм для таких ситуаций будет работать быстрее, то скорее всего из-за его сложности он будет работать медленнее на базовых ситуациях, что в результате сделает его медленнее в среднем. Вообщем я бы не стал дальше пытаться его оптимизировать.
var base = [1, 1, 1, 2, 3, 4, 5, 6, 1, 1, 2, 3, 1, 1, 2, 3];
var find = [1, 1, 2, 3];
var rez = [];
var yes;
var max = base.length - find.length;
for (var i = 0; i <= max; i++) {
yes = true;
for (var j = 0; j < find.length; j++) {
if (base[i + j] != find[j]) {
yes = false;
break;
}
}
if (yes) {
rez.push(i);
}
}
console.log(rez);
Обновлено
Для максимально быстрого поиска необходимо использовать конечные автоматы.
Смотрим алгоритм Ахо — Корасик.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.IntStream; class Main { // Вспомогательная функция для вставки <key, value> пара в multimap private static<K, V> void insert(Map<K, List<V>> hashMap, K key, V value) { // если ключ виден в первый раз, инициализируем список hashMap.putIfAbsent(key, new ArrayList<>()); hashMap.get(key).add(value); } // Вспомогательная функция для печати подмассива `nums[i, j]` public static void printSubarray(int[] nums, int i, int j) { System.out.println(IntStream.range(i, j + 1) .mapToObj(k -> nums[k]) .collect(Collectors.toList())); } // Функция поиска подмассивов с заданной суммой в массиве public static void printAllSubarrays(int[] nums, int target) { // создаем карту для хранения конечного индекса всех подмассивов с // сумма элементов на данный момент Map<Integer, List<Integer>> hashMap = new HashMap<>(); // Для обработки случая, когда начинается подмассив с заданной суммой // с 0-го индекса insert(hashMap, 0, —1); int sum_so_far = 0; // обход заданного массива for (int index = 0; index < nums.length; index++) { // сумма элементов на данный момент sum_so_far += nums[index]; // проверяем, существует ли хотя бы один подмассив с заданной суммой if (hashMap.containsKey(sum_so_far — target)) { List<Integer> list = hashMap.get(sum_so_far — target); for (Integer value: list) { printSubarray(nums, value + 1, index); } } // вставляем пару (на данный момент, текущий индекс) в карту insert(hashMap, sum_so_far, index); } } public static void main (String[] args) { int[] nums = { 3, 4, —7, 1, 3, 3, 1, —4 }; int target = 7; printAllSubarrays(nums, target); } } |
SVD102 1 / 1 / 1 Регистрация: 12.10.2015 Сообщений: 207 |
||||
1 |
||||
Найти подмассив в массиве29.10.2015, 12:59. Показов 22375. Ответов 6 Метки нет (Все метки)
Надо найти в массиве не один элемент, а целый подмассив! Если подмассив найден в массиве, то вернуть нужно минимальный индекс, с которого начинается подмассив в исходном массиве. Например, поиск подмассива «3,4» в массиве «1,2,3,4,3,4» должен вернуть 2. Не могу придумать алгоритм.( Добавлено через 19 минут
Нужно дописать функцию ContainsAtIndex(array, subArray, i)
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
29.10.2015, 12:59 |
Ответы с готовыми решениями: Найти в массиве подмассив 3 х 3, сумма элементов которого максимальна В массиве чисел найти подмассив длины m с максимальной суммой Выделить подмассив в двумерном массиве Значит, имеется массив В массиве чисел найдите самый длинный подмассив из одинаковых чисел 6 |
Даценд 5863 / 4740 / 2940 Регистрация: 20.04.2015 Сообщений: 8,361 |
||||
29.10.2015, 14:06 |
2 |
|||
Решение
3 |
Komaryan 16 / 16 / 10 Регистрация: 23.03.2010 Сообщений: 103 |
||||
29.10.2015, 14:33 |
3 |
|||
Решение
0 |
Bein 0 / 0 / 0 Регистрация: 17.09.2016 Сообщений: 99 |
||||
25.09.2016, 15:44 |
4 |
|||
Даценд, а как создать отдельный метод ContainsAtIndex, то есть как оформить метод, чтобы след код был корректен?
То есть нам нужен еще один метод ContainsAtIndex, чтобы в нем был алгоритм поиска подмассива в массиве. Как это сделать?
0 |
Даценд 5863 / 4740 / 2940 Регистрация: 20.04.2015 Сообщений: 8,361 |
||||
25.09.2016, 16:08 |
5 |
|||
Bein,
3 |
afront 1493 / 1208 / 821 Регистрация: 29.02.2016 Сообщений: 3,597 |
||||
25.09.2016, 16:09 |
6 |
|||
0 |
Ren Trapnest 36 / 34 / 13 Регистрация: 03.06.2010 Сообщений: 215 |
||||
12.12.2017, 14:11 |
7 |
|||
SVD102,
0 |
Как эффективно найти все возможные подмассивы массива?
5 ответов
Лучший ответ
Подмассив массива A равен A[i..j]
, где 0 <= i <= j < n
, где n — длина массива.
На языке C это можно рассчитать так:
#include <stdio.h>
int main(){
int A[] = {1,2,3,4,5};
int len=sizeof(A)/sizeof(int);
for( int i=0; i<len; i++ ){
for( int j=i; j<len; j++ ){ // Now A[i..j] is the subarray
for( int k=i; k<=j; k++ )
printf("%d ", A[k]);
printf("n");
}
}
return 0;
}
4
Ankit Vallecha
29 Сен 2019 в 15:15
Возьмите первый элемент. У вас есть первый подмассив. У вас есть второй элемент? Добавьте и этот, вот и второй. Если есть третий, добавьте его и так далее. Мы делаем это до тех пор, пока не получим последний подмассив, который технически представляет собой весь массив размера n. Но теперь мы возвращаемся на две позиции назад и пропускаем элемент n-1, и вы добавляете n-й элемент … вы получаете новый подмассив.
Обратите внимание, как это включает в себя включение некоторых элементов, но пропуск других. Угадайте, рекурсия — это именно то, что вам нужно. Постройте постепенно, пропуская элементы после того, как они были использованы (и есть другие, которые можно использовать).
< Сильный > псевдокод :
Array x;
collection SubArrays= {0}
SubArrays.AddSubArrays(x,0);
collection AddSubArrays(array, init,next){
if(next>array.limit){
return {0};
}
collection c.Add(array[init]
while return not {0}
i=init+1;
while return not {0}
c.AddSubArrays(array,init+1,i)
i= i+1
endwhile
return c
}
4
Neeraj Kumar
26 Окт 2017 в 12:02
Мы можем использовать функцию substr, чтобы найти все возможные подмассивы.
Фрагмент кода:
#include<bits/stdc++.h>
using namespace std;
void generateSubstring(string str)
{
if(str.size()==0)
{
return;
}
else
{
for(int i=0; i<str.size(); i++)
{
for(int j=1; j<=str.size()-i; j++)
{
cout<<str.substr(i, i+j)<<endl;
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
string str;
getline(cin, str);
generateSubstring(str);
return 0;
}
3
rashedcs
8 Июл 2017 в 13:13
Попробуйте следующий код:
def subarray(a, n) :
for i in range(0,n):
for j in range(i, n) :
for k in range(i, j+1) :
print(a(k), end=" ")
print("n", end=" ")
a=[1, 2,3,4,5]
n=len(a)
print( all non - empty subarrays are:-)
subarray(a, n)
2
Subhodeep Chandra
27 Дек 2019 в 12:09
В JavaScript
function subarray(arr){
let sub = []
for(let i=0;i<=arr.length-1;i++){
for(let j=arr.length-1;j>=i;j--){
sub.push(arr.slice(i,j+1))
}
}
return sub
}
0
David Buck
6 Июн 2020 в 18:32