Longest Consecutive Sequence in Array C++ - c++

I have to create a function that will find the longest consecutive sequence of integers in an array.
The array is this:
{1,2,3,4,4,4,5,7,9,10}
Note: repeated numbers in a sequence are skipped.
Here is my code:
int longestSequence(const int arr[], int size)
{
int currentSeq = 1;//set to 1 because all sequences are at least 1
int maxSeq;
for (int i = 1; i < size; i++)
{
if (arr[i] == arr[i-1]);//skip repeated numbers
else if (arr[i-1] == (arr[i] - 1))//check if index is 1 greater than last
{
currentSeq++;
}
else //if not reset and hold last sequence value as max
{
maxSeq = currentSeq;
currentSeq = 1;
}
}
if (currentSeq > maxSeq) //if the last index of the array was last in the sequence
{
maxSeq = currentSeq;
}
return maxSeq;
}
My code keeps returning 2 for this array but obviously it should be 5.
Any help would be appreciated.

You have 3 sequences in your array:
1, 2, 3, 4, 4, 4, 5 which has 5 consecutive numbers.
5, 7 which is not consecutive and will return 1.
7, 9 which will also return one.
9, 10 which has 2 consecutives and will return two.
In your loop you're doing this:
for (int i = 1; i < size; i++)
{
if (arr[i] == arr[i-1]);//skip repeated numbers
else if (arr[i-1] == (arr[i] - 1))//check if index is 1 greater than last
{
currentSeq++;
}
else //if not reset and hold last sequence value as max
{
maxSeq = currentSeq; // <-- You're resetting your maxSequence even if
// currentSeq is smaller.
currentSeq = 1;
}
}
Change your loop as following:
for (int i = 1; i < size; i++)
{
if (arr[i] == arr[i-1])
continue; //It is a good practice to skip the rest of the loop's
//checks if you already know you're not gonna need them.
//The continue keyword skips only the current iteration of
//the loop and improves intent readability.
else if (arr[i-1] == (arr[i] - 1))//check if index is 1 greater than last
{
currentSeq++;
}
else //if not reset and hold last sequence value as max
{
currentSeq = 1; //This line stays.
//You only want to reset it under these specific conditions.
}
if (currentSeq > maxSeq) // Now you'll get the last sequence as well.
maxSeq = currentSeq;
}
You can remove that check outside of the loop and go straight to the return. The last currentSeq will be properly registred if it is bigger than maxSeq.
Also, when I did this change I got a compile error because the new if (currentSeq > maxSeq) inside the loop tries to read maxSeq before it is ever set. So change the declaration of maxSeq to int maxSeq = 0.
With these changes I got the expected value of 5.

By running your program in a debugger with the sample array you provided, I determined that the variable currentSeq does indeed reach the value 5 and this value 5 is correctly written to maxSeq. However, later in the program, maxSeq gets overwritten by the value 1 and then 2.
Before overwriting maxSeq, you must determine whether it already contains a higher value than currentSeq. You already do this in one case, when you have reached the end of the array. But you don't do this in the other case.
For such a comparison to work, you must also initialize maxSeq, not just currentSeq. Otherwise, maxSeq may contain a very large number and always be larger than currentSeq.

#include <iostream>
void Log(int idx, int currentSeq, int maxSeq) {
printf("current[%d] = %d, max[%d] = %d\n", idx, currentSeq, idx, maxSeq);
}
int LongestSequence(int* arr, int size) {
int currentSeq = 1;
int maxSeq = 1; // max should be initialized as well
Log(0, currentSeq, maxSeq);
for (int i = 1; i < size; i++) {
if (arr[i] == arr[i - 1]) {
} else if (arr[i - 1] == (arr[i] - 1)) {
currentSeq++;
} else {
currentSeq = 1;
}
// maxSeq should be updated in time, otherwise it would be tossed away
maxSeq = std::max(maxSeq, currentSeq);
Log(i, currentSeq, maxSeq);
}
return maxSeq;
}
int main() {
int arr[] = {1, 2, 3, 4, 4, 4, 5, 7, 9, 10};
std::cout << LongestSequence(arr, sizeof(arr) / sizeof(arr[0])) << std::endl;
}
Output:
current[0] = 1, max[0] = 1
current[1] = 2, max[1] = 2
current[2] = 3, max[2] = 3
current[3] = 4, max[3] = 4
current[4] = 4, max[4] = 4
current[5] = 4, max[5] = 4
current[6] = 5, max[6] = 5
current[7] = 1, max[7] = 5
current[8] = 1, max[8] = 5
current[9] = 2, max[9] = 5
5

Related

strange error in main and incorrect reading of a vector [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 months ago.
Improve this question
hi I was writing a code where near the vectors it returns true if they are placed in ascending order otherwise false, when I try to start the code it gives me this error that I cannot understand
main.cpp:9:5: error: conflicting types for 'main'
int main(int, const char *[]) {
^
./solution.cpp:30:5: note: previous definition is here
int main()
^
1 error generated.
the other error happens in the vector inAscOrder_3 in which it should return false but I don't understand why it doesn't return it.
the code.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
bool isAscOrder(vector<int> arr)
{
int size_array = arr.size()-1;
int min = 0;
int max = 0;
for (int j = 0; j < size_array; j++)
{
if (min == 0)
{
min = arr[j];
max = arr[j];
}
if (arr[j] > min)
{
return true;
}
if(arr[j]<min)
{
return false;
}
}
return false;
}
int main()
{
vector<int> inAscOrder_1 = {1, 2, 4, 7, 19}; // returns true
vector<int> inAscOrder_2 = { 1, 2, 3, 4, 5 }; // returns true
vector<int> inAscOrder_3 = { 1, 6, 10, 18, 2, 4, 20 }; // returns false
vector<int> inAscOrder_4 = { 9, 8, 7, 6, 5, 4, 3, 2, 1 }; // returns false because the numbers are in DESCENDING order
//test 1
if (isAscOrder(inAscOrder_1) == true)
{
cout << "test #1 passed! " << endl;;
}
if (isAscOrder(inAscOrder_2) == true)
{
cout << "test #2 passed! "<<endl;
}
if (isAscOrder(inAscOrder_3) == false)
{
cout << "test #3 passed! "<<endl;
}
if (isAscOrder(inAscOrder_4) == false)
{
cout << "test #4 passed! ";
}
return 0;
}
In your average C++ program, the main function is the singular entry and exit point for the program. When your executable is called, the program starts at main, and once main returns, the program releases all of its allocated resources and is terminated.
Your first issue arises because you have multiple declarations of the main function; the first is located at main.cpp:9:5, and the second is located at solution.cpp:30:5
As for your second issue, your function does not do what you think it does; any correlation between your expected outputs and the real outputs are pure coincidence.
bool isAscOrder(vector<int> arr)
{
// This gets the size of your vector, then subtracts 1.
// size_array is now the index of the last element in the vector,
// and can be accessed with arr[size_array] without throwing an exception.
int size_array = arr.size()-1;
int min = 0;
int max = 0; //< you never actually read the value from this
// This condition is true until (j == size_array), and once it is the for loop breaks the loop.
// Keep in mind, size_array is currently set to the index of the last ELEMENT in your vector;
// That means you're always skipping the last element in the vector.
// You can avoid this by checking either ( j < arr.size() ) or ( j <= size_array )
// ▼
for (int j = 0; j < size_array; j++)
{
// This is always triggered on the first loop because min is always set to 0 the first time.
// if every number in the vector is 0 (except for the last one),
// then this will trigger every single time.
// ▼▼▼▼▼▼▼▼
if (min == 0)
{
// ▼ Sets min to the value at arr[j]
min = arr[j];
max = arr[j];
// ▲ Sets max to the value at arr[j],
// so max is now equal to min.
// For tests 1-3, that value is `1`;
// for test 4, that value is `9`
// Here we check if the value at arr[j] is greater than min, and if it is-
// -we immediately break from the for loop and return true.
if (arr[j] > min)
{
return true;
}
// Here we check if the value at arr[j] is less than min, and if it is-
// -we immediately break from the for loop and return false.
if(arr[j]<min)
{
return false;
}
//< we never reach this point a second time unless ( arr[0] == arr[1] )
}
//< This is only ever reached if every element of arr except for
// the last one is set to the same number.
return false;
}
As an example of what this function is doing, I debugged it for you:
As you can see, the function returned true on the second loop; this is because arr[1](2) is greater than min(1).
inAscOrder_1
Returns true when j == 1, because inAscOrder_1[1] == 2, and 2 > 1
inAscOrder_2
Returns true when j == 1, because inAscOrder_2[1] == 2, and 2 > 1
inAscOrder_3
Returns true when j == 1, because inAscOrder_3[1] == 6, and 6 > 1
inAscOrder_4
Returns false when j == 1, because inAscOrder_4[1] == 8, and 8 < 9
This is a working example of what your function should be doing:
bool isAscOrder(vector<int> arr)
{
if (arr.size() < 2) //< make sure arr[1] exists
return false;
// Start at 1 Don't skip the last element
// ▼ ▼▼▼▼▼▼▼▼▼▼▼▼▼
for (int i{ 1 }; i < arr.size(); ++i) {
// Check if arr[i] is less than or equal to arr[i - 1], this is
// why we started at 1 instead of 0; to prevent accessing arr[-1]
// ▼ ▼▼▼▼▼
if (arr[i] <= arr[i - 1])
return false;
// This approach works because if the sequence is in ascending order,
// each number in arr is never less than the previous one. (except for arr[0], which doesn't have a previous number)
}
return true;
}
You can allow a vector with repeated numbers to return true with this variant:
bool isAscOrder(vector<int> arr, bool allowRepeats = false)
{
if (arr.size() < 2) //< make sure arr[1] exists
return false;
for (int i{ 1 }; i < arr.size(); ++i) {
if (allowRepeats
? ( arr[i] < arr[i - 1] ) //< when allowing repeats, return false if the current element is less than the previous one.
: ( arr[i] <= arr[i - 1] ) //< when disallowing repeats, return false if the current element is less than or equal to the previous one.
)
{
return false;
}
}
return true;
}
When you're writing C++ code, having access to a debugger is incredibly important; if you're on Windows you can download and use Visual Studio Community for free.

Longest Increasing Sub-sequence within a vector using recursion?

So for my lab I'm attempting to find the longest sequence of numbers within a given vector.
for example, if the numbers you had were [5, 15, 16, 4, 8, 9, 10] the longest increasing sub-sequence would be 4, the 4, 8, 9, 10 portion. I have to be able to find this without using loops and using recursion and I've gotten this far, but I can't quite figure out how to hold a variable for the longest sequence and also have a variable for the temporary longest sequence, it just has to return the integer value of the length of the sequence, not the sequence itself. Thank you and any help or critiques are appreciated!
int increasing_sequence_recursive(std::vector<int> &numbers, int startIdx) {
if (startIdx == numbers.size()) {
return '/0';
} else if (numbers[startIdx] < numbers[startIdx + 1]) {
int tempSeq = 1 + increasing_sequence_recursive(numbers, startIdx + 1);
return tempSeq;
}
return increasing_sequence_recursive(numbers, startIdx + 1);
}
EDIT:
'''
int maxTemp(std::vector<int> &numbers, int startIdx, int maxSoFar) {
if (startIdx == numbers.size()) {
return maxSoFar;
} else if (numbers[startIdx] < numbers[startIdx + 1]) {
int temp = 1 + maxTemp(numbers, startIdx + 1, maxSoFar);
if (temp > maxSoFar) {
maxSoFar = temp;
}
temp = 1;
} else {
return maxTemp(numbers, startIdx + 1, maxSoFar);
}
}
'''
I created this helper function to do the main recursion but for some reason the temp value is never resetting so the value is basically the added length of both sequences.

How would I write an algorithm to find the greatest jump from number to number in a sequence?

If your sequence is 4 2 1, the largest jump is from 4 to 2. If your sequence is 3 10 5 16 8 4 2 1, the largest jump is from 5 to 16.
I've made an algorithm however I'm not completely sure what I have done wrong (whever I haven't made the loop properly, set my variables correctly, or something else). I'm not sure what I need to set my index, BiggestDiff, or CurrentDiff too. I tried using a while loop to compare each number in my vector but I get zero (I'm assuming because I set BiggestDiff to zero)
If anyone can point me in the right direction, show me an example, or something else, that will be greatly appreciated.
Here is my code below
int findBiggestDiff(std::vector<int> sequence)
{
int index = 0;
int BiggestDiff = 0 ;
int CurrentDiff = BiggestDiff;
CurrentDiff = std::abs(sequence[index] - sequence[index + 1]);
while (index < sequence.size())
{
if (CurrentDiff > BiggestDiff)
{
BiggestDiff = CurrentDiff;
}
return index;
}
}
Try this:
{
int indexOfBiggestJump = 0;
int BiggestDiff = 0 ;
int CurrentDiff = BiggestDiff;
for(int i = 0; i < sequence.size() - 1; i++) {
CurrentDiff = std::abs(sequence[i] - sequence[i + 1]);
if (CurrentDiff > BiggestDiff)
{
BiggestDiff = CurrentDiff;
indexOfBiggestJump = i;
}
}
return indexOfBiggestJump;
}
There are several errors in your code.
your return index literally does nothing, only returns index (which will be 0) always.
you are not saving the index of the biggest jump anywhere.
if you are looking positions i and i + 1, you must go until sequence.size() - 1, otherwise you will look out of the bounds of sequence.
You aren't recalculating CurrentDiff at all. Also, your return statement in the in the wrong spot. You can do something like this (not tested)
int findLargest( const std::vector<int> &sequence ) {
if ( sequence.size() < 2 ) return -1; // if there's not at least two elements, there's nothing valid.
int index = 0;
int biggestIndex = -1;
int biggestDiff = -1;
while (index < sequence.size() - 1) // -1 so that the +1 below doesn't go out of range
{
// get the current difference
int currentDiff = std::abs(sequence[index] - sequence[index + 1]);
if (currentDiff > biggestDiff)
{
// update stats
biggestIndex = index;
biggestDiff = currentDiff;
}
++index;
}
return biggestIndex
}
int main() {
//…
int index = findLargest( sequence );
if ( index != -1 ) {
std::cout << "Biggest difference was between " << sequence[index] << " and " << sequence[index+1];
}
}

move zeros in an array to the end

"The question comes under a broad category of "Array Transformation". This category is the meat of tech interviews. Mostly because arrays are such a simple and easy to use data structure. Traversal or representation doesn't require any boilerplate code and most of your code will look like the Pseudocode itself.
The 2 requirements of the question are:
Move all the 0's to the end of array.
All the non-zero elements must retain their original order."
My thinking:
to find the zeros and exchange their positions with the last numbers
/* int swap;
int n=nums.size()-1;
for(int i=0;i<nums.size();i--){
if(nums[i]==0){
swap = nums[i];
nums[i] = nums[n];
nums[n] = swap;
n--;
}
}
My input
[0,1,0,3,12]
Output
[1,3,12,0,0]
Diff
Expected
[1,3,12,0,0]
And I did not know why the correct answer(the part) is :
(int n = 0, cur = 0; cur < nums.size(); cur++) {
if (nums[cur] != 0) {
swap(nums[n++], nums[cur]);
}
}
}
Can you use the standard library? std::stable_partition() makes it trivial. Something like
std::stable_partition(nums.begin(), nums.end(),
[](const auto &n){ return n != 0; });
For the question of how the solution in your post works:
At the start of the first iteration, n is 0, cur is 0, and nums is [0,1,0,3,12]. nums[cur] is 0, so nothing happens. At the start of the second iteration, cur is 1, and nums[cur] is 1, so the swap and increment of n happens.
Now n is 1, cur is 2, and nums is [1,0,0,3,12]. nums[cur] is 0, so nothing happens in the third iteration. In the fourth iteration, with cur now 3, a swap happens. So at the start of the the fifth iteration, n is 2, cur is 4, and nums is [1,3,0,0,12]. I'll leave it to you to work out what happens in that step.
Basically, when n is not equal to cur, it's the index of a 0 element that can be swapped with a non-0 element that cur is the index of. This swapping eventually moves all 0's to the end.
My take on the problem, minimal std library usage. Probably not the most efficient, but it does the trick.
#include "stdafx.h"
#include <iostream>
int main()
{
int src[] = { 0, 1, 0, 3, 0, 12 }; // Output: 1 3 12 0 0 0 check
// = { 0, 3, 0, 1, 0, 0, 12, 0, 5 }; // Output: 3 1 12 5 0 0 0 0 0 check
int n = sizeof(src) / sizeof(src[0]);
for (int x = 0; x < n; x++) {
for (int y = x + 1; y < n; y++) {
if (src[x] == 0 && src[y] != 0) {
int swap = src[x];
src[x] = src[y];
src[y] = swap;
}
}
}
for (int i = 0; i < n; i++) {
std::cout << src[i] << " ";
}
return 0;
}

heap-buffer-overflow on address

Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array.
Example 1:
Input: [3,0,1]
Output: 2
My approach is read each element and then multiply that index by -1. Whichever array index remains positive is the one that's missing (I have to handle zero separately)
My code causes a heap overflow on line where I try to multiply the element by -1
class Solution {
public:
int missingNumber(vector<int>& nums) {
bool zeroFound = false;
for(auto i = nums.begin(); i < nums.end(); i++) {
if(*i == 0) {
zeroFound = true;
} else {
int value = *i;
printf("Inner %d %d\n", value, nums[value -1]);
//nums[value - 1] = value * (-1);
}
}
if(!zeroFound) {
return 0;
} else {
int count = 1;
for(auto i = nums.begin(); i < nums.end(); i++, count++) {
if(*i > 0) {
return count;
}
}
}
return -1;
}
};
Learn to use a debugger.
Your problem is that after the first run through the loop, the input is [3, 0, -3]. When you process the final element, you try and access element -4, which is never going to end well.
Even if you use the absolute value of the element, your first run will have overwritten the last element - so you can no longer tell whether the input was [3, 0, 1] or [3, 0, 2].