Google Interview Question for SDE1s


Team: GFS
Country: United States
Interview Type: Phone Interview




Comment hidden because of low score. Click to expand.
2
of 4 vote

Since Next() and HasNext() methods are exactly the same for CPeekIterator as for CIterator, we just duplicate them without any changes.
The only difference in CPeekIterator is that Peek() needs to return next value without advancing the iterator. Solution is to store CIterator inside CPeekIterator and in case of Peek() create a temporary iterator. It will return next value, but advancing is not important, since it's temporary value.

class CIterator
{
	int Next();
	bool HasNext();
};

class CPeekIterator
{
	CIterator currIt;

	CPeekIterator(CIterator it) : currIt(it) {}

	int Next(){
		return currIt.Next();
	}
	bool HasNext(){
		return currIt.HasNext();
	}
	int Peek(){
		CIterator tmp = currIt;
		return tmp.Next();
	}
};

- marut December 08, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Since tmp refers the same object, calling CPeekIterator.Peek causes advancing in currIt and correspondingly it works as a regular Next().
A right solution for this is to have an internal var that contains current element:

private CIterator iter;

        private int current;

        public CPeekIterator(CIterator inputIter)
        {
            this.iter = inputIter;
            this.current = int.MinValue;
        }

        public int Next()
        {
            return this.current = this.iter.Next();
        }

        public int Peek()
        {
            return this.current;
        }

- Alex M. April 23, 2016 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

as it was a phone interview, I think the interviewer wanted to hear that to implement Peek() method we should just take Next() method and eliminate the line "counter++;" from it.

- zr.roman November 24, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

No I am sure the answer is to copy the CIterator to another instance, use it's Next() method and then discard it.

- Srinath November 24, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

No. We have get peek by using only HasNext and Next function only. We don't have control on CIterator class

- John samuel November 24, 2015 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

If we could modify the existing code in Iterator, we wouldn't need the 2nd class :-)

What the interviewer is expecting is that for you to put a 'wrapper' class on top of CIterator. E.g. you can read the 'next' and 'peek' element on initialization, and then advance them both on each 'next()' request, or you can have two CIterator classes inside, and advance one ahead of the other (ugly, but easier to implement) etc...

- caliostro November 24, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

yes, variant with copying constructor in CIterator (deep copy) is quite possible.

- zr.roman November 24, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

but the variant «to read the 'next' and 'peek' element on initialization, and then advance them both on each 'next()' request» is bad.
Imagine, you have 1 billion elements in collection. When your iterator will point to last element, the Peek() method will work as follows:
1) invoke Next() method;
2) invoke First() method;
3) in loop invoke Next() method (1 billion - 1) times.

Moreover, in the initial task there is no method "First()", so if it is really is not allowed then the variant with copying constructor in CIterator is the only one variant.

- zr.roman November 24, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 2 vote

If it is possible to augment all methods in CPeekIterator , CIterator could be wrapped in the follwowing way.

public class CPeekIterator  {
  CIterator it;
  int peekVal ;
  boolean hasNext;
  public CPeekIterator(CIterator it)  {
   this.it = it; 
   hasNext = it.hasNext();
   peekVal = it.next();
 }
 int next() {
	int temp = peekVal;
	peekVal = next;
	return temp;
 }
 int peek() {
	return peekVal;
 }
boolean hasNext() {
     int temp = hasNext;
     hasNext = it.next();
     return temp;
 }
}

- EPavlova November 24, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 vote

Added some correction on code:

public class CPeekIterator  {
  CIterator it;
  int peekVal ;
  boolean hasNext;
  public CPeekIterator(CIterator it)  {
   this.it = it; 
   hasNext = it.hasNext();
   peekVal = it.next();
 }
 int next() {
	int temp = peekVal;
	peekVal = it.next();
	return temp;
 }
 int peek() {
	return peekVal;
 }
boolean hasNext() {
     boolean temp = hasNext;
     hasNext = it.hasNext();
     return temp;
 }
}

- EPavlova November 24, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 vote

Provided before executing Next() or Peek(), you will check HasNext()

class CPeekIterator : CIterator
{
    public:
	   CPeekIterator() : nextVal(false)
	   {
	   }
       virtual int Next()
       {
		if(hasNext)	
		{	
			hasNext = false;
			return nextVal;
		}
		return CIterator::Next();
        }		
        virtual int peek()
        {
		if(!hasNext)
		{
			hasNext = true;
			nextVal = CIterator::next();
		}		
		return nextVal;
	}   
	virtual int HasNext() const
	{
		return hasNext ? true : CIterator::HasNext();
	}		 		 	
    private:
	int nextVal;
	bool hasNext;
};

- rishab99999 November 25, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 vote

public class CIterator
{
	int[] items;
	int index = 0;

	public CIterator(int[] items)
	{
		this.items = items;
	}

	public int Next()
	{
		if (!HasNext())
			throw new InvalidOperationException();

		return items[index++];
	}

	public bool HasNext()
	{
		return index < items.Length;
	}
}

public class CPeekIterator
{
	private CIterator iterator;
	private bool prevAdvanced = false;
	private int peek;
	private bool hasNext;


	public CPeekIterator(CIterator iterator)
	{
		this.iterator = iterator;
	}

	public int Next()
	{
		if (prevAdvanced)
		{
			prevAdvanced = false;
			return this.peek;
		}

		return iterator.Next();
	}

	public bool HasNext()
	{
		if (prevAdvanced)
			return this.hasNext;

		return iterator.HasNext();
	}
	
	public int Peek()
	{
		if (prevAdvanced)
			return this.peek;

		this.hasNext = iterator.HasNext();
		this.prevAdvanced = true;
		this.peek = iterator.Next();
		return this.peek;
	}
}

- hnatsu November 27, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Class Citerator {
Int Next();
Boolean hasNext();
}

Class CPeekIterator {
Int Next();
Boolean hasNext();
Int Peek();
Citerator it;
Int curr;
int lastCall = -1; // 0 for peek, 1 for next

Boolean hasNext() {
	If (it.hasNext())
		Return true;
	Else {
	If (lastCall == 1)
		Return false;
	If (lastCall == 0)
	Return true;
If (lastCall == -1)
	Return false;
}
}

Int Peek() {
	If (lastCall == -1) {
		If (it.hasNext())
			Curr = it.next();
		Else 
			Curr = -1;
			lastCall = 0;
			Return curr;
}
	Else If (lastCall == 0)
		Return curr;
		Else {
			If (it.hasNext())
			Curr = it.next();
		Else 
			Curr = -1;
			lastCall = 0;
			Return curr;
}
}

Int Next() {
	If (lastCall == -1) {
		lastCall = 1;
		If (it.hasNext())
	Return it.next();
Return -1;
}
Else If (lastCall == 0) {
	lastCall = 1;
Return Curr;
}
Else {
	If (it.hasNext())
	Return it.next();
Return -1;
}	
}
}

- Chendu May 21, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

// Time:  O(1) per peek(), next(), hasNext()
// Space: O(1)

// Below is the interface for Iterator, which is already defined for you.
// **DO NOT** modify the interface for Iterator.
class Iterator {
    struct Data;
	Data* data;
public:
	Iterator(const vector<int>& nums);
	Iterator(const Iterator& iter);
	virtual ~Iterator();
	// Returns the next element in the iteration.
	int next();
	// Returns true if the iteration has more elements.
	bool hasNext() const;
};

class PeekingIterator : public Iterator {
public:
    PeekingIterator(const vector<int>& nums) : Iterator(nums), has_next_(Iterator::hasNext()) {
        // Initialize any member here.
        // **DO NOT** save a copy of nums and manipulate it directly.
        // You should only use the Iterator interface methods.
    }

    // Returns the next element in the iteration without advancing the iterator.
    int peek() {
        if (!has_peeked_) {
            has_peeked_ = true;
            val_ = Iterator::next();
        }
        return val_;
    }

    // hasNext() and next() should behave the same as in the Iterator interface.
    // Override them if needed.
    int next() {
        val_ = peek();
        has_peeked_ = false;
        has_next_ = Iterator::hasNext();
        return val_;
    }

    bool hasNext() const {
        return has_next_;
    }

private:
    int val_;
    bool has_next_;
    bool has_peeked_ = false;
};

- johnsvakel November 24, 2015 | Flag Reply


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More