-1

I'm trying to implement amazon interview question.

Find the maximum sum of lengths of non-overlapping contiguous subarrays with k as the maximum element.
Ex: Array: {2,1,4,9,2,3,8,3,4} and k = 4
Ans: 5
{2,1,4} => Length = 3
{3,4} => Length = 2
So, 3 + 2 = 5 is the answer

I have implement program:

#include <iostream>
using namespace std;

int main()
{
        int a[] = {2,1,4,9,2,3,8,3,4,2};
        int cnt = 0, i = 0, j = 0, ele, k = 4;
        int tmp = 0, flag = 0;

        ele = sizeof(a)/sizeof(a[0]);

        for(j = 0; j < ele; )
        {
                i = j;
              //while( i < ele && a[i++] <= k) //It's working fine
                while(a[i] <= k && i++ < ele)  // It's not work
                {
                        cnt++;
                        cout<<"while"<<endl;
                }

                while(j < i)
                {
                        if(a[j++] == k)
                        {
                                flag = 1;
                        }
                }

                if(flag == 1)
                {
                        tmp += cnt;
                        flag = 0;
                }
                cnt = 0;
                j = i;
        }
        cout<<"count : "<<tmp<<endl;
        return 0;
}

In my program, I used

while( i < ele && a[i++] <= k)

It's working fine and gives correct output.

But, If I use

while(a[i] <= k && i++ < ele)

then my program is stuck. Why?

Jayesh
  • 4,755
  • 9
  • 32
  • 62

2 Answers2

3

With while(a[i] <= k && i++ < ele) you can actually go out of bounds of the array a, leading to undefined behavior.

If i is the last index of the array, then i++ < ele is actually true (because the postfix ++ operator returns the old value before incrementing), and then in the loop i will be out of bounds.

Undefined behavior is, well, undefined and could mean that just about anything could happen. From crashes to infinite or stuck loops.

A better solution would be to use prefix increment instead, as in ++i < ele.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    isnt is already UB, because `i++` and `a[i]` appears in the same expression? – 463035818_is_not_an_ai Aug 11 '17 at 08:55
  • 1
    @tobi303 No, the left-hand side is sequenced before the right-hand side of a `&&` or `||` expression (see e.g. [this evaluation order reference](http://en.cppreference.com/w/cpp/language/eval_order), especially [rule](http://en.cppreference.com/w/cpp/language/eval_order#Rules) 6). – Some programmer dude Aug 11 '17 at 08:56
0

The different between while( i < ele && a[i++] <= k) and while(a[i] <= k && i++ < ele) is: while( i < ele && a[i++] <= k) will increment i first and get value later but while(a[i] <= k && i++ < ele) will compare i and ele first and increment i later.

So in your code, when program run out of while(a[i] <= k && i++ < ele) , i is equal 3, but while( i < ele && a[i++] <= k) is equal to 4. That's why the problem caused

msc
  • 33,420
  • 29
  • 119
  • 214
Tony Teng
  • 105
  • 8