简体   繁体   中英

Contiguous sub sequence with max success rate in a sequence given a minimum sub sequence length

I'm trying to solve an algorithmic problem where the premises revolves around an input sequence that consists of 0s and 1s along with a minimum length l for the output subsequence. The problem asks for the subsequence which has the highest rate of 1s (number of ones in the subsequence divided by the length of the subsequence). Further background and sample input/output to the problem can be found here .

I have come up with a solution that passes all tests except for the last one and I am trying to figure out what my current implementation is lacking. My approach is to use a dynamically resizeable sliding window while storing the maximum rate of the sliding window along with the length of that maximum rated window. I think the way that I'm moving (growing and shrinking) my window is the problem, but I'm having trouble figuring out what to change.

This is how I move my window:

static void max_rate(long min_len, string sequence) {
  long left_window = 0, right_window = min_len - 1;

  long best_left = 0, best_len = 0, most_ones = 0;
  long double best_success_rate = -1;
  for (;;) {
    auto tmp = sequence.substr(left, right - left + 1);

    long n_ones = count_ones(tmp);
    long double success_rate = (long double)n_ones / (long double)tmp.length();

    if (success_rate >= best_success_rate) {
      best_success_rate = success_rate;
      best_left = left;
      best_len = right - left + 1;
      most_ones = n_ones;
    }

  // Window sliding starts here
  bool can_move_right = (right + 1) < (long)sequence.length();
  bool can_move_left = (right - left + 1 - 1) >= min_len;

    if (can_move_right && sequence.at(right + 1) == '1') {
    ++(right);
    } else if (can_move_right && sequence.at(right + 1) == '1') {
    ++(right);
    } else if (can_move_left && (sequence.at(left + 1) == '0')) {
    ++left;
    } else if (can_move_right) {
      ++(right);
    } else {
      break;
    }

  cout << best_left + 1 << " ";
  cout << best_len << endl;

I'm basically checking:

  1. Grow the window if you can increase the rate
  2. Otherwise, if possible (considering our minimum size requirement), shrink the window if you can increase the rate
  3. Otherwise, if possible (-), shrink the window
  4. Otherwise, if possible (we are not at the end of the sequence) grow the window

I must be missing something here I think

According to the code you posted, for input

8, "0011101011"

the sequence would seem to be

0 0 1 1 1 0 1 0 1 1
l             r
l               r
l                 r
  l               r

which gives us:

zero-based index 1, interval length 9
and ratio 6 / 9 = 0.6666666666666666

but the correct answer is

ratio 0.75
zero-based index 2, interval length 8

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM