2

I'm looking for an algorithm that given a list like:

[1, 1, 2, 1, 1, 5, 1, 1, 1, 1, 2, 1]

can find and return all subsequences of a given value. For example, if given the value 1, the function would return [[1, 1], [1, 1], [1, 1, 1, 1], [1]].

I believe this is similar to problems such as summing up all subsequences of an array or finding all the subsequences of a given string but algorithms was never my strong suit. The answer can be psuedo-code or language agnostic. And if you wouldn't mind, could you explain the complexity of the solution?

I can explain what I need this for if that helps. Comment if you want that.

9
  • can you explain how all of your sub-lists are supposed to have the value 1? ... What is the property here? (My best guess: you want all subsequences where all values in it are at most 1) Commented Apr 20, 2016 at 4:20
  • also: last time I checked [1,1,1,1,1,1,1,1,1] would be a subsequence too see the definition Commented Apr 20, 2016 at 4:22
  • True yes, it would be a subsequence, but all the solutions I was looking at were about either summing up a subsequence or finding the longest subsequence, not returning the actually sequences themselves. And no, 1 was just an arbitrary example I chose. Commented Apr 20, 2016 at 4:28
  • so you just want to split the list as soon as there is an element neq 1? Commented Apr 20, 2016 at 4:29
  • No I'm doing something much more complex than that, having to do with CoreVideo and AVFoundation in iOS, I was just wondering about how I'd accomplish this on a high level. Commented Apr 20, 2016 at 4:30

3 Answers 3

1

We can do this in O(n) time complexity by scanning the array twice. Pseudocode:

//use an array list so we can access element at an index in O(1) time
outputArrays = new ArrayList<int[]> //list of arrays

//loop to declare arrays of outputs - this scans each element once
int currLen = 0;
for (item in inputArray) {
 if (item = itemToLookFor) {
  currLen++;
 }else if (currLen > 0) {
  currLen = 0;
  outputArrays.add(new int[currLen]);
 }
}

//loop to actually populate the output - this scans each element once
currLen = 0;
currIndex = 0;
for (item in inputArray) {
 if (item = itemToLookFor) {
  outputArrays.getElement(currIndex)[currLen] = item;
  currLen++;
 }else if (currLen > 0) {
  currLen = 0;
  currIndex++;
 }
}

Let me know if there is anything i can clarify.

Sign up to request clarification or add additional context in comments.

7 Comments

So first you build up the output arrays and then you populate the arrays. Is there any reason that can't be done within one loop? And perchance, is there a more functional way to approach the problem?
@startupthekid none - and of course there is a functional way - once you actually said what you want it's gonna by a one-liner in any reasonable FP language - the question is only if you want filter (all (== 0)) . subsequences or a simple splitBy
Well I guess what I really want is all subsequences that pass a filter condition. So say for example the filter is { x % 2 == 0 } and the input array was [1, 2, 2, 3, 4, 4], the output would be [[2, 2], [4, 4]] if that makes sense.
@startupthekid I'm sure there are many ways to do this natively, probably with a single call. I answered like this because I thought you wanted to see an algorithm (as the question is tagged), not a library call. And if you don't need your output as arrays, you can do this in a single pass.
@startupthekid meeting a condition is no problem - just make a helper method that checks that condition given an input and replace the line if (item = itemToLookFor) with your helper method.
|
0

Let a be initial array, res - resulting array of sequences, curSeq - a current sequence, given_value - a given value.

res = []
curSeq = []
for i = 1..length(a)
    if a[i] != given_value
        if curSeq has at least one item
            append curSeq to res
        end if
        curSeq = []
    else
        append given_value to curSeq
    end if
end for
if curSeq has at least one item
    append curSeq to res
end if

As you can see the time complexity is O(n) where n is the length of initial array.

Comments

0

Here is the O(n) solution. Here arr is input array of sequence and sequence is array for sub-sequence. You can save sequence another array for your answer.

arr = [1, 1, 2, 1, 1, 5, 1, 1, 1, 1, 2, 1]; // here is your
selectNumber = 1 //take input for selected input
sequence = [];
for (i: 0 to arr.length) {
  if (arr[i] == selectNumber) {
    sequence.push(selectNumber);
  } else {
    if(sequence.length > 0) {
      print sequence;
      sequence = [] // empty sequence array as it is already printed or saved
    }
  }
}

if (sequence > 0) {
  print sequence; // last sequence if exist
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.