Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- You are given a string s consisting of the characters 'a', 'b', and 'c' and a non-negative integer k. Each minute, you may take either the leftmost character of s, or the rightmost character of s.
- Return the minimum number of minutes needed for you to take at least k of each character, or return -1 if it is not possible to take k of each character.
- Example 1:
- Input: s = "aabaaaacaabc", k = 2
- Output: 8
- Explanation:
- Take three characters from the left of s. You now have two 'a' characters, and one 'b' character.
- Take five characters from the right of s. You now have four 'a' characters, two 'b' characters, and two 'c' characters.
- A total of 3 + 5 = 8 minutes is needed.
- It can be proven that 8 is the minimum number of minutes needed.
- Example 2:
- Input: s = "a", k = 1
- Output: -1
- Explanation: It is not possible to take one 'b' or 'c' so return -1.
- Constraints:
- 1 <= s.length <= 10^5
- s consists of only the letters 'a', 'b', and 'c'.
- 0 <= k <= s.length
- LINK- https://leetcode.com/problems/take-k-of-each-character-from-left-and-right/
- */
- class Solution {
- public:
- int binarySearch(vector<int> &arr, int low, int high, int req){
- int res=-1;
- while(low<=high){
- int mid=(low+high)/2;
- if(arr[mid]>=req){
- res=mid;
- low=mid+1;
- }
- else{
- high=mid-1;
- }
- }
- return res;
- }
- int takeCharacters(string s, int k) {
- if(k==0){
- return 0;
- }
- int n=s.size();
- vector<int> A(n,0);
- vector<int> B(n,0);
- vector<int> C(n,0);
- for(int i=n-1;i>=0;i--){
- if(i<n-1){
- A[i]+=A[i+1];
- B[i]+=B[i+1];
- C[i]+=C[i+1];
- }
- s[i]=='a' ? A[i]++ : (s[i]=='b' ? B[i]++ : C[i]++);
- }
- if(A[0]<k || B[0]<k || C[0]<k){
- return -1;
- }
- int a=0;
- int b=0;
- int c=0;
- int res=INT_MAX;
- for(int i=0;i<n;i++){
- s[i]=='a' ? a++ : (s[i]=='b' ? b++ : c++);
- if(a>=k && b>=k && c>=k){ // taking only from left side
- res=min(res,i+1);
- break; // if your ith index contains all k a,b,c then it is time to break cuz you will not get any smaller than this moving ahead.
- }
- if(A[n-i-1]>=k && B[n-i-1]>=k && C[n-i-1]>=k){ // taking only from right side
- res=min(res,i+1);
- break;
- }
- int requiredA=k-a;
- int requiredB=k-b;
- int requiredC=k-c;
- int indexA=binarySearch(A,i+1,n-1,requiredA);
- int indexB=binarySearch(B,i+1,n-1,requiredB);
- int indexC=binarySearch(C,i+1,n-1,requiredC);
- int index=min({indexA,indexB,indexC});
- if(index==-1){ // not possible
- continue;
- }
- res=min(res,(i+1)+(n-index));
- }
- return res==INT_MAX ? -1 : res;
- }
- };
- /*
- THOUGHT PROCESS-
- If I have count of a,b,c till a certain point index, how can I find the rest from i+1 till n-1 in less time.
- NOTE- THERE IS A SLIDING WINDOW PROBLEM SOLVING IN O(N) TIME
- */
Advertisement
Add Comment
Please, Sign In to add comment