0% found this document useful (0 votes)
360 views23 pages

Two Pointers

Uploaded by

Nishant Patil
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
360 views23 pages

Two Pointers

Uploaded by

Nishant Patil
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

3Sum Closest.

txt
3Sum With Multiplicity.txt
3Sum.txt
4Sum.txt
Container With Most Water.txt
Count the Number of Good Partitions.txt
Longest Mountain in Array.txt
Longest Word in Dictionary through Deleting.txt
Longest_Substring_Without_Repeating_Characters.txt
Max Consecutive Ones III.txt
Maximum_Erasure_Value.txt
Minimize Maximum Pair Sum in Array.txt
Number of Subsequences That Satisfy the Given Sum Condition.txt
Push Dominoes.txt
Remove Duplicates from Sorted Array II.txt
Remove Duplicates from Sorted Array.txt
Reverse Vowels of a String.txt
Successful Pairs of Spells and Potions.txt
Two Sum II - Input array is sorted.txt
Valid Triangle Number.txt

/*
MY YOUTUBE VIDEO FOR THIS Qn :
https://www.youtube.com/watch?v=hGLjwiPRh0U&list=PLpIkg8OmuX-K6A0sEPFxOSJh4_AjCGAFf&inde
x=6
Company Tags : Facebook, Amazon, Microsoft, Oracle
Leetcode Link : https://leetcode.com/problems/3sum-closest/
*/

class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
int n = nums.size();
sort(nums.begin(), nums.end());

int closestSum = 100000;

for(int i = 0; i<n-2; i++) {

int l = i+1, r = n-1;


while(l < r) {
int sum = nums[i] + nums[l] + nums[r];

if(abs(target-sum) < abs(target-closestSum)) {


closestSum = sum;
}

if(sum > target)


r--;
else
l++;
}
}
return closestSum;
}
};
/*
Company Tags : Quora
Leetcode Link : https://leetcode.com/problems/3sum-with-multiplicity/
*/

//Approach-1 (Sorting- Two Pointer)


class Solution {
public:
long ans = 0;
void twoSum(vector<int>& nums, int k, int target) {
int i = k, j = nums.size()-1;
while(i < j) {
if(nums[i]+nums[j] > target)
j--;
else if(nums[i] + nums[j] < target)
i++;
else {
if(nums[i] != nums[j]) {
int c1 = 1, c2 = 1;
while(i < j && nums[i] == nums[i+1]) {
c1++;
i++;
}

while(j > i && nums[j] == nums[j-1]) {


c2++;
j--;
}

ans += (c1*c2);
i++;
j--;
} else {
int duplicates = j-i+1;
ans += (duplicates*(duplicates-1)/2);
break;
}
}
}
}
int threeSumMulti(vector<int>& nums, int target) {
ans = 0;
sort(nums.begin(), nums.end());
for(int i = 0; i<nums.size()-2; i++) {
twoSum(nums, i+1, target-nums[i]);
}
long K = 1e9+7;
return ans%K;
}
};

//Approach-2 (Making use of constraint 0 <= arr[i] <= 100)


class Solution {
public:
int threeSumMulti(vector<int>& arr, int target) {
long ans = 0;
long K = 1e9+7;

vector<int> cnt(101);
for(int& x:arr) {
cnt[x]++;
}

for(int num1 = 0; num1<=100; num1++) {


for(int num2 = num1; num2<=100; num2++) {
int num3 = target - (num1 + num2);
if(num3 >= 0 && num3 <= 100) {
if(num1 == num2 && num2 == num3) {
long n = cnt[num1];
//we choose 3 elements from n i.e. nC3
ans += n*(n-1)*(n-2)/(3*2*1);
} else if(num1 == num2) {
long n1 = cnt[num1]; //choose 2 from here i.e. nC2
long n2 = cnt[num3]; //choose this frequency for all nC2 from above (n1)

ans += (n1*(n1-1)/2) * n2;


} else if(num1 < num2 && num2 < num3) {
ans += cnt[num1] * cnt[num2] * cnt[num3];
}
}
}
}

return ans%K;

}
};
/*
MY YOUTUBE VIDEO ON THIS Qn :
https://www.youtube.com/watch?v=_cBWWebTVpI&list=PLpIkg8OmuX-K6A0sEPFxOSJh4_AjCGAFf&ind
ex=4
Company Tags : Amazon, Facebook, Google
Question on GfG : Find triplets with zero sum
(https://practice.geeksforgeeks.org/problems/find-triplets-with-zero-sum/1)
Leetcode Qn Link : https://leetcode.com/problems/3sum/
*/

class Solution {
public:
void twoSum(vector<int>& nums, int k, vector<vector<int>>& result, int target) {
//Two pointer technique (Sorted array) Things you must not forget in interviews

int i = k, j = nums.size()-1;
while(i < j) {
if(nums[i]+nums[j] > target)
j--;
else if(nums[i] + nums[j] < target)
i++;
else {
result.push_back({-target, nums[i], nums[j]});
while(i < j && nums[i] == nums[i+1]) i++;
while(i < j && nums[j] == nums[j-1]) j--;
i++; //Things you must not forget in interviews
j--; //Things you must not forget in interviews
}
}
}
vector<vector<int>> threeSum(vector<int>& nums) {
if(nums.size() < 3) //Things you must not forget in interviews
return {};
vector<vector<int>> result;
sort(nums.begin(), nums.end());
for(int i = 0; i<nums.size()-2; i++) { //(i<nums.size()-2)Things you must not forget in interviews
if(i!= 0 && nums[i] == nums[i-1]) { //Things you must not forget in interviews
continue;
}
twoSum(nums, i+1, result, -nums[i]);
}
return result;
}
};
/*
Company Tags : Amazon, Microsoft, Google
Leetcode Link : https://leetcode.com/problems/4sum/
*/

class Solution {
public:
void twoSum(vector<vector<int>>& result, vector<int>& nums, int i, int j, int n, int target) {
int k = j+1, l = n-1;
while(k<l) {
if(nums[k] + nums[l] > target)
l--;
else if(nums[k] + nums[l] < target)
k++;
else {
result.push_back({nums[i], nums[j], nums[k], nums[l]});
while( k < n-1 && nums[k] == nums[k+1]) k++;
while(l > 0 && nums[l] == nums[l-1]) l--;
k++;
l--;
}
}
}
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int n = nums.size();
vector<vector<int>> result;
if(n < 4)
return result;
for(int i = 0; i<n-3; i++) {
if(i > 0 && nums[i] == nums[i-1])
continue;
for(int j = i+1; j<n-2; j++) {
if(j > i+1 && nums[j] == nums[j-1])
continue;
int subTarget = target-(nums[i]+nums[j]);
twoSum(result, nums, i, j, n, subTarget);
}
}
return result;
}
};
/*
Company Tags : Bloomberg, Facebook, Google, Amazon, Adobe
Leetcode Link : https://leetcode.com/problems/container-with-most-water/
*/

//Why does my solution given below works ?


/*
Idea / Proof (Gathered from Discussion Section of Leetcode from some intelligent programmers) :
The widest container (using first and last line) is a good candidate, because of its width.
Its water level is the height of the smaller one of first and last line. All other containers
are less wide and thus would need a higher water level in order to hold more water. The smaller
one of first and last line doesn’t support a higher water level and can thus be safely removed from
further consideration.
*/

//Approach-1 (Two pointer Greedy (O(N))


class Solution {
public:
int maxArea(vector<int>& height) {
int n = height.size();
int i = 0, j = n-1;

int water = 0;
while(i<j) {

//start from the smallest one and calculate water


int h = min(height[i], height[j]);
int w = j-i;
int area = h*w;
water = max(water, area);

if(height[i] < height[j])


i++;
else
j--;
}

return water;
}
};

//Approach-2 (Two pointer Greedy (O(N)) (It’s similar to Approach-1)


//Just that we are eliminating heights at one go
class Solution {
public:
int maxArea(vector<int>& height) {
int n = height.size();
int i = 0, j = n-1;

int water = 0;
while(i<j) {

//start from the smallest one and calculate water


int h = min(height[i], height[j]);
int w = j-i;
int area = h*w;
water = max(water, area);

//Then move towards large one because we can have better answer
if(height[i] <
while(i < j && height[i] <= h)
i++;
//Same, move towards large one because we can have better answer
while(i < j && height[j] <= h)
j--;
}

return water;
}
};
/*
MY YOUTUBE VIDEO ON THIS Qn : https://www.youtube.com/watch?v=fyyjpElDeuY
Company Tags : I will update soon
Leetcode Link : https://leetcode.com/problems/count-the-number-of-good-partitions/
*/

/************************************************************ C++
************************************************************/
//Approach (Using simple 2 Pointer)
//T.C : O(n)
//S.C : O(n)
class Solution {
public:
int M = 1e9 + 7;
int numberOfGoodPartitions(vector<int>& nums) {
int n = nums.size();
unordered_map<int, int> last_index; //number, last index

for (int i = 0; i < n; ++i) {


last_index[nums[i]] = i;
}

int i = 0;
int j = max(0, last_index[nums[0]]);

int result = 1;
while(i < n) {
if(i > j) { //we found one partition
result = (result*2)%M;
}
j = max(j, last_index[nums[i]]);
i++;
}

return result;
}
};

/************************************************************ C++
************************************************************/
//Approach (Using simple 2 Pointer)
//T.C : O(n)
//S.C : O(n)
import java.util.HashMap;
import java.util.Map;

class Solution {
int M = 1000000007;

public int numberOfGoodPartitions(int[] nums) {


int n = nums.length;
Map<Integer, Integer> last_index = new HashMap<>();

for (int i = 0; i < n; ++i) {


last_index.put(nums[i], i);
}

int i = 0;
int j = Math.max(0, last_index.get(nums[0]));

int result = 1;
while (i < n) {
if (i > j) {
result = (int) ((result * 2L) % M);
}

j = Math.max(j, last_index.get(nums[i]));
i++;
}

return result;
}
}
/*
Compnay Tags : NIL
Leetcode Link : https://leetcode.com/problems/longest-mountain-in-array/
*/

class Solution {
public:
int longestMountain(vector<int>& A) {
int n = A.size();
if(n < 3)
return 0;
int mid = 1;
int result = 0;
while(mid < n-1) {
if(A[mid-1] < A[mid] && A[mid] > A[mid+1]) {
int start = mid-1;
int end = mid+1;
while(start > 0 && A[start] > A[start-1]) {
start--;
}

while(end < n-1 && A[end] > A[end+1]) {


end++;
}

result = max(result, end-start+1);


}
mid++;
}
return result;
}
};
/*
Company Tags : Google
Leetcode Link : https://leetcode.com/problems/longest-word-in-dictionary-through-deleting/
*/

class Solution {
public:
string s1 = "";
//They wanted to check if you comeup with isSubsequence approach or not
bool isSubsequence(string& s2) {
int i = 0;
int j = 0;

int m = s1.length();
int n = s2.length();

while(i < m && j < n) {


if(s1[i] == s2[j])
j++;
i++;
}

return j==n;
}
string findLongestWord(string s, vector<string>& d) {
string result = "";
s1 = s;
for(string str:d) {
if(isSubsequence(str)) {
if(str.length() > result.length())
result = str;
else if(str.length() == result.length() && str < result)
result = str;
}
}

return result;
}
};
/*
Company Tags : Morgan Stanley, Amazon, Microsoft, Housing.com
Leetcode Link : https://leetcode.com/problems/longest-substring-without-repeating-characters/
*/

//Approach-1 (Using set data structure and two pointer technique)


//Time : O(2*n)
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_set<char> st;
int l = 0;

int n = s.length();
int i = 0;
int j = 0;
while(j < n) {
if(!st.count(s[j])) {
st.insert(s[j]);
l = max(l, (int)st.size());
j++;
} else {
st.erase(s[i]);
i++;
/*
Example : "a b c d e a a"
When you are at 5th index, you notice that you saw ’a’ somewhere before, you delete it from
set
Now, you add this ’a’ (5th index) in the set and move ahead at 6th index.
Now, you see that ’a’ (6th index) is somewhere behind because it’s in the set.
But you keep deleting from set until you delete this ’a’ (5th index) from the set.
So, effectively you are iterating array 2 times in worst case. So, time = O(2*n)
*/
}
}
return l;
}
};

//Approach-2 (Using map data strcture and two pointer technique)


//Time : O(n)
/*
Instead of deleting character one by one, we can directly jump ’i’ just after the last appearance of a
character.
We will use to store indices of character. So, in that way we don’t have to move ’i’ one by one.
Now one thing to note,
Example : "a a b a a b z b b"
When you reach at index 4 (’a’), you move i = mp[’a’] + 1. i.e. ’i’ is now 4
Now, When you are at 5th index (’b’), you notice that you have ’(b, 2)’ in map. So, you make i = map[’b’]
+ 1;
i.e. i becomes 3 but did you notice you had made i = 4 above. This is an issue.
So, we do this : i = max(i, mp[ch]+1); //which ever is larger we make that jump for ’i’
*/
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n = s.length();
int res = 0;

int i = 0, j = 0;
unordered_map<char, int> mp;

while(j < n) {
char ch = s[j];
if(!mp.count(ch)) {
//If not in map, update map and calculate length
mp[ch] = j;
res = max(res, j-i+1);
} else {
//if already present in map, make proper i jump and then calculate length
i = max(i, mp[ch] + 1);
mp[ch] = j; //Don’t forget to update new index of ch
res = max(res, j-i+1);
}
j++;
}

return res;
}
};

//Approach-3 (Just simplifying Approach-2. Notice some statements are common in if and else block.
Take them outside
//Time : O(n)
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n = s.length();
int res = 0;

int i = 0, j = 0;
unordered_map<char, int> mp;

while(j < n) {
char ch = s[j];
if(mp.count(ch)) {
i = max(i, mp[ch] + 1);
}
mp[ch] = j;
res = max(res, j-i+1);
j++;
}
return res;
}
};
/*
Company Tags : Google (With some Variations)
Leetcode Link : https://leetcode.com/problems/max-consecutive-ones-iii/
*/

//Approach-1 (Two Pointer Technique)


class Solution {
public:
void moveUntilOneCount(vector<int>& nums, int& count, int& i, int& j, int &k) {
if(count > k) {
while(j <= i && count > k) {
if(nums[j] == 0) {
count--;
}
j++;
}
}
}
int longestOnes(vector<int>& nums, int k) {
int n = nums.size();

if(k >= n)
return n;

int result = 0;
int count = 0;
int i = 0, j = 0;
while(i < n) {
if(nums[i] == 0) {
count++;
moveUntilOneCount(nums, count, i, j, k);
}
result = max(result, i-j+1);
i++;
}
return result;
}
};

//Approach-2 (2 pointer techinique with slight improvement)


class Solution {
public:
int longestOnes(vector<int>& nums, int k) {
int n = nums.size();

if(k >= n)
return n;

int result = 0;
int count = 0;
int i = 0, j = 0;
while(i < n) {
if(nums[i] == 0)
count++;
if(count > k) {
count -= nums[j] == 0 ? 1 : 0; //decrement k only if you are crossing leaving 0 behind
j++;
}
result = max(result, i-j+1);
i++;
}
return result;
}
};
/*
Leetcode Weekly Contest Qn
Company Tag : NIL (Let me know if you find any :-) )
Leetcode Link : https://leetcode.com/problems/maximum-erasure-value/
*/

//Approach-1 (Smart)
class Solution {
public:
int maximumUniqueSubarray(vector<int>& nums) {
int n = nums.size();
vector<int> cus(n+1, 0);
for(int i = 0; i<n; i++)
cus[i+1] = cus[i] + nums[i];

vector<int> t(100001, -1);


int start = 0;
int maxS = 0;

for(int end = 0; end<n; end++) {


start = max(start, t[nums[end]]+1);
maxS = max(maxS, cus[end+1]-cus[start]);
t[nums[end]] = end;
}

return maxS;
}
};

//Approach-2 (Simple and intuitive)


class Solution {
public:
int maximumUniqueSubarray(vector<int>& nums) {
int n = nums.size();
if(n == 1)
return nums[0];

int sum = 0;
int i = 0, j = 0;
unordered_map<int, int> mp;
vector<int> cumS(n, 0);
cumS[0] = nums[0];
for(int i = 1; i<n; i++) {
cumS[i] = cumS[i-1] + nums[i];
}

while(i < n) {
if(!mp.count(nums[i])) {
mp[nums[i]] = i;
i++;
} else {
if(mp[nums[i]] >= j) {
int temp = cumS[i-1] - (j>0 ? cumS[j-1] : 0);
sum = max(sum, temp);
j = mp[nums[i]] + 1;
}
mp[nums[i]] = i;
i++;
}
}

int temp = 0;
if(j < n) {
temp = cumS[n-1] - (j>0 ? cumS[j-1] : 0);
}

return max(sum, temp);


}
};
/*
MY YOUTUBE VIDEO ON THIS Qn : https://www.youtube.com/watch?v=1L9C3a38fHU
Company Tags : AMAZON
Leetcode Link :
https://leetcode.com/problems/minimize-maximum-pair-sum-in-array/description/
Similar Leetcode Porblem : Leetcode 881. Boats to Save People
*/

/***************************************************************** C++
******************************************************************************/
//Simple 2-pointer approach
//T.C : O(nlogn) due to sorting
//S.C : O(1)
class Solution {
public:
int minPairSum(vector<int>& nums) {
sort(begin(nums), end(nums));

int maxResult = 0;

int i = 0, j = nums.size()-1;

while(i < j) {
int sum = nums[i] + nums[j];
maxResult = max(maxResult, sum);
i++;
j--;
}

return maxResult;

}
};

/***************************************************************** JAVA
******************************************************************************/
//Simple 2-pointer approach
//T.C : O(nlogn) due to sorting
//S.C : O(1)
class Solution {
public int minPairSum(int[] nums) {
Arrays.sort(nums);

int maxResult = 0;

int i = 0, j = nums.length - 1;

while (i < j) {
int sum = nums[i] + nums[j];

maxResult = Math.max(maxResult, sum);


i++;
j--;
}

return maxResult;
}
}
/*
MY YOUTUBE VIDEO ON THIS Qn : https://www.youtube.com/watch?v=eGqs55VTP3I
Company Tags : Amazon
Leetcode Link :
https://leetcode.com/problems/number-of-subsequences-that-satisfy-the-given-sum-condition/
*/

//Approach-1 (Produce all subsequences, find min and max and check)
//This will give TLE

//Approach-2 (Using Sorting + Two Pointer Approach)


class Solution {
public:
int M = 1e9+7;
int numSubseq(vector<int>& nums, int target) {
int n = nums.size();
//1. Sort
sort(begin(nums), end(nums));

vector<int> power(n);
power[0] = 1;

for(int i = 1; i<n; i++) {


power[i] = (power[i-1] * 2) % M;
}

//2. l = 0, r = n-1
int l = 0, r = n-1;
int result = 0;
while(l <= r) {

if(nums[l] + nums[r] <= target) {


int diff = r-l;
result = (result % M + power[diff]) % M;
l++;
} else {
r--;
}

return result;
}
};
/*
Company Tags : Google
Leetcode Link : https://leetcode.com/problems/push-dominoes/
*/

//Approach-1 (O(n) time : Two Pointer Technique)


/*
In this approach, you just need to find sections like this
X. . . .X
i j
Where X can be ’R’ or ’L’ and in between there can be as many dots
Now,
- you know the length of mid part
- If char[i] == char[j] == ’R’, means all go towards right (R)
- char[i] == char[j] == ’L’, means all go towards Left (L)
- If char[i] = ’L’ and char[j] = ’R’, means middle part is not affected so the remain ’.’
- If char[i] = ’R’ and char[j] = ’L’, then it will affect the middle part.
The middle_part/2 close to i will be affected by ’R’ and middle_part/2 close to j will be
effected by ’L’ and the last mid point (middle_part%2) will be unaffected due to equal
force from left and right so it remains ’.’
*/
class Solution {
public:
string pushDominoes(string dominoes) {
string s = "L" + dominoes + "R";
int n = s.length();
string result = "";
for(int i = 0, j = 1; j<n; j++) {
if(s[j] == ’.’) continue;

int midPartLength = j-i-1;


if(i > 0)
result.push_back(s[i]);

if(s[i] == s[j])
result += string(midPartLength, s[i]);
else if(s[i] == ’L’ && s[j] == ’R’)
result += string(midPartLength, ’.’);
else
result += string(midPartLength/2, ’R’) + string(midPartLength%2, ’.’) + string(midPartLength/2,
’L’);
i = j;
}

return result;
}
};

//Approach-2 (O(n) time : Finding closest ’L’ and closest ’R’)


class Solution {
public:
string pushDominoes(string dominoes) {
int n = dominoes.length();

vector<int> rightClosestL(n);
vector<int> leftClosestR(n);

//Moving right to left to find rightClosestL


for(int i = n-1; i>=0; i--) {
if(dominoes[i] == ’L’)
rightClosestL[i] = i; //L starts from me
else if(dominoes[i] == ’.’)
rightClosestL[i] = i < n-1 ? rightClosestL[i+1] : -1;
else
rightClosestL[i] = -1;
}

//Moving left to right to find leftClosestR


for(int i = 0; i<n; i++) {
if(dominoes[i] == ’R’)
leftClosestR[i] = i; //R starts from me
else if(dominoes[i] == ’.’)
leftClosestR[i] = i > 0 ? leftClosestR[i-1] : -1;
else
leftClosestR[i] = -1;
}

string result(n, ’ ’);

for(int i = 0; i<n; i++) {


int distRightL = abs(i-rightClosestL[i]); //distance from ’R’ towards my left direction
int distLeftR = abs(i-leftClosestR[i]); //distance from ’L’ towards my right direction
if(rightClosestL[i] == leftClosestR[i])
result[i] = ’.’;
else if(rightClosestL[i] == -1) //No force from right direction towards left, so move R
result[i] = ’R’;
else if(leftClosestR[i] == -1) //No force from left direction towards right, so move L
result[i] = ’L’;
else if(distLeftR == distRightL) //Equal force from left and right
result[i] = ’.’;
else
result[i] = distRightL < distLeftR ? ’L’: ’R’; //which ever force is greater (either from left by ’R’ or
from right by ’L’)
}

return result;
}
};

//Approach-3 (O(n) time : Using Force Simulation)


class Solution {
public:
string pushDominoes(string dominoes) {
int n = dominoes.length();

vector<int> forces(n);

//Move from left to right and look for right force ’R’
int force = 0; //initially
for(int i = 0; i<n; i++) {
if(dominoes[i] == ’R’)
force = n; //My max power towards Right starts from here and it will decrease as I progress
else if(dominoes[i] == ’L’)
force = 0; //I can’t give force towards Right :-(
else
force = max(force-1, 0); //I told ya, my power decreases as I progress and hit a ’.’

forces[i] = force;
}

//Move from right to left and look for left force ’L’
force = 0; //initially
for(int i = n-1; i>=0; i--) {
if(dominoes[i] == ’L’)
force = n; //My max power towards Left starts from here and it will decrease as I progress
else if(dominoes[i] == ’R’)
force = 0; //I can’t give force towards Left :-(
else
force = max(force-1, 0); //I told ya, my power decreases as I progress and hit a ’.’

forces[i] -= force; //resultant force (that’s why I am subtracting)


}

//Now I will find resultant direction on each domino basis of resultant force on them
string result(n ,’.’);
for(int i = 0; i<n; i++) {
if(forces[i] < 0)
result[i] = ’L’;
else if(forces[i] > 0)
result[i] = ’R’;
}
return result;

}
};
/*
Company Tags : Google, Facebook, Expedia, Microsoft
Leetcode Link : https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/
*/

class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n = nums.size();

//since we need an element atleast 2 times


if(n<=2) {
return n;
}

int left = 2, right = 2;


//left = culprit index whom we will always choose if we want to put a new value
//right = it will iterate over all elements
while(right < n) {
if(nums[left-2] != nums[right]) {
nums[left] = nums[right];
left++;
//now culprint index left has been punished, so we need to move on
//with our new culprit index i.e. i++
}
right++;
}
return left;
}
};
/*
MY YOUTUBE VIDEO ON THIS Qn : https://www.youtube.com/watch?v=06ALbFrgIoQ
Company Tags : Facebook, Google, Amazon, Microsoft, Expedia, LinkedIn
Leetcode Link : https://leetcode.com/problems/remove-duplicates-from-sorted-array/
*/

/**************************************************************** C++
****************************************************************/
//T.C : O(n)
//S.C : O(1)
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n = nums.size();
if(n == 0) return 0;
int i = 0, j = 1;
while(j < n) {
if(nums[i] != nums[j]) nums[++i] = nums[j];
j++;
}

return i+1;
}
};

/**************************************************************** JAVA
****************************************************************/
//T.C : O(n)
//S.C : O(1)
public class Solution {
public int removeDuplicates(int[] nums) {
int n = nums.length;
if (n == 0) return 0;
int i = 0, j = 1;

while (j < n) {
if (nums[i] != nums[j]) {
nums[++i] = nums[j];
}
j++;
}

return i + 1;
}
}
/*
MY YOUTUBE VIDEO ON THIS Qn : https://www.youtube.com/watch?v=pqzvpK8zTHU
Company Tags : Google, Zoho, Flipkart,
Leetcode Link : https://leetcode.com/problems/reverse-vowels-of-a-string/
GfG Link : https://practice.geeksforgeeks.org/problems/reversing-the-vowels5304/1
*/

//Simply using Two pointer technique


class Solution {
public:
bool isVowel(char &ch) {
return ch ==’a’ || ch == ’e’ ||
ch ==’i’ || ch == ’o’ ||
ch == ’u’ ||
ch ==’A’ || ch == ’E’ ||
ch ==’I’ || ch == ’O’ ||
ch == ’U’;
}
string reverseVowels(string s) {
int n = s.length();
int i = 0;
int j = n-1;

while(i < j) {
if(!isVowel(s[i])) i++;

else if(!isVowel(s[j])) j--;

else {
swap(s[i], s[j]);
i++;
j--;
}
}

return s;
}
};
/*
MY YOUTUBE VIDEO ON THIS Qn : <soon>
Company Tags : MICROSOFT
Leetcode Link : https://leetcode.com/problems/successful-pairs-of-spells-and-potions/
*/

//Approach-1 : Using lower_bound STL


//In my Binary Search sub-repo -
https://github.com/MAZHARMIK/Interview_DS_Algo/blob/master/Arrays/Binary%20Search/Successful%2
0Pairs%20of%20Spells%20and%20Potions.cpp

//Approach-2 : Using self written Binary Search for lower bound


//In my Binary Search sub-repo -
https://github.com/MAZHARMIK/Interview_DS_Algo/blob/master/Arrays/Binary%20Search/Successful%2
0Pairs%20of%20Spells%20and%20Potions.cpp

//Approach-3 (Using 2 pointers)


class Solution {
public:
vector<int> successfulPairs(vector<int>& spells, vector<int>& potions, long long success) {
vector<pair<int,int>> sortedSpells;
for (int i = 0; i< spells.size(); ++i) {
sortedSpells.push_back({ spells[i], i });
}

// Sort the ’spells with index’ and ’potions’ array in increasing order.
sort(sortedSpells.begin(), sortedSpells.end());
sort(potions.begin(), potions.end());

vector<int> answer(spells.size());
int m = potions.size();
int potionIndex = m - 1;

// For each ’spell’ find the respective ’minPotion’ index.


for (const auto& [spell, index] : sortedSpells) {

while (potionIndex >= 0 && (long long) spell * potions[potionIndex] >= success) {
potionIndex -= 1;
}
answer[index] = m - (potionIndex + 1);
}

return answer;
}
};
/*
MY YOUTUBE VIDEO FOR THIS Qn : https://www.youtube.com/watch?v=gsSLay-wcaw
Company Tags : Amazon
Leetcode Link : https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/
*/

class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
int i = 0, j = numbers.size()-1;

while(i < j) {
if(numbers[i]+numbers[j] == target) {
return {i+1, j+1};
}

if(numbers[i]+numbers[j] > target)


j--;
else
i++;
}
return {};
}
};
/*
Company Tags : Google (variation in qn)
Leetcode Link : https://leetcode.com/problems/valid-triangle-number/
*/

//Approach-1 (Using Binary Search)


class Solution {
public:
int triangleNumber(vector<int>& nums) {
int n = nums.size();
if(n < 3)
return 0;

sort(begin(nums), end(nums));
int count = 0;
for(int i = 0; i<n-2; i++) {
for(int j = i+1; j<n-1; j++) {
int k = j+1;
int sum = nums[i] + nums[j];

if(k < n) {
int idx = lower_bound(begin(nums)+k, end(nums), sum) - begin(nums);
count += (idx-j-1);
}
}
}

return count;
}
};

//Approach-2 (O(n^2) Using concept similar two 3-Sum)


class Solution {
public:
int triangleNumber(vector<int>& nums) {
int n = nums.size();
if(n < 3)
return 0;

sort(begin(nums), end(nums));
int count = 0;
for(int i = n-1; i>1; i--) {
int l = 0, r = i-1;

while(l < r) {
if(nums[l] + nums[r] > nums[i]) {
count += (r-l);
r--;
} else {
l++;
}
}
}
return count;
}
};

/*
Note : If we use 3-SUM approach like as shown below :
for(int i = 0; i<n-2; i++) {
int l = i+1, r = n-1;
while(l < r) {
///code
}
}

We won’t be getting correct result.


Example :
2 2 3 4
i l r

nums[l]+nums[r] is not greater than nums[r]


So, we increase l

2 2 3 4
i l r
nums[l]+nums[r] > nums[r], we increment count by 1

But if you notice we missed the triplet {2, 2, 3} XXXXXXXX ALERT!!!!!


-----------------------------

So, let’s take same example with Approach-2


2 2 3 4
l r i

nums[l]+nums[r] is greater than nums[r],


it means nums[l+1]+nums[r] > nums[r] or sure
Also, nums[l+2]+nums[r] > nums[r] or sure and so on until l < r
So, {2, 3, 4}, {2, 3, 4} are valid

Now, we decrement i--

2 2 3 4
l r i
Here also, {2, 2, 3} is valid until l < r
*/

You might also like