Array third 50

¡Supera tus tareas y exámenes ahora con Quizwiz!

746. Min Cost Climbing Stairs On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). Once you pay the cost, you can either climb one or two steps. You need to find minimum cost to reach the top of the floor, and you can either start from the step with index 0, or the step with index 1. Input: cost = [10, 15, 20] Output: 15

use dp from end to start. class Solution { public: int minCostClimbingStairs(vector<int>& cost) { int size = cost.size(); vector<int> dp(size + 1, INT_MAX); dp[size] = 0; for(int i = size-1; i >= 0; i --) { int v1 = cost[i] + dp[i+1]; int v2 = cost[i] + (i + 2 > size? 0: dp[i+ 2]); dp[i] = min(v1, v2); } return min(dp[0], dp[1]); } };

941. Valid Mountain Array Given an array A of integers, return true if and only if it is a valid mountain array. Recall that A is a mountain array if and only if: A.length >= 3 There exists some i with 0 < i < A.length - 1 such that: A[0] < A[1] < ... A[i-1] < A[i] A[i] > A[i+1] > ... > A[A.length - 1] Input: [3,5,5] Output: false

we first skip all the increasing index, and check the index is not 0 and not size-1, and arr[i] != arr[i+1], then skip all the decreasing index, and check the index is size-1. class Solution { public: bool validMountainArray(vector<int>& A) { int size = A.size(); if(size < 3) return false; int i = 0; while(i + 1 < size && A[i] < A[i+1]) i ++; if(i == 0 || i == size-1) return false; if(i+1 < size && A[i] == A[i+1]) return false; while(i + 1 < size && A[i] > A[i+1]) i ++; if(i + 1 < size) return false; return true; } };

888. Fair Candy Swap Since they are friends, they would like to exchange one candy bar each so that after the exchange, they both have the same total amount of candy. (The total amount of candy a person has is the sum of the sizes of candy bars they have.) Return an integer array ans where ans[0] is the size of the candy bar that Alice must exchange, and ans[1] is the size of the candy bar that Bob must exchange. Input: A = [1,2], B = [2,3] Output: [1,2]

we get the ave size each person finally own, and the diff: ave - suma. class Solution { public: vector<int> fairCandySwap(vector<int>& A, vector<int>& B) { int sum1 = 0; int sum2 = 0; for(auto& num: A) sum1 += num; unordered_set<int> numSet; for(auto& num: B) { sum2 += num; numSet.insert(num); } int ave = (sum1 + sum2) / 2; int diff = ave - sum1; vector<int> ans(2); for(auto& num: A) if(numSet.find(num + diff) != numSet.end()) return {num, num + diff}; return {}; } };

775. Global and Local Inversions We have some permutation A of [0, 1, ..., N - 1], where N is the length of A. The number of (global) inversions is the number of i < j with 0 <= i < j < N and A[i] > A[j]. The number of local inversions is the number of i with 0 <= i < N and A[i] > A[i+1]. Return true if and only if the number of global inversions is equal to the number of local inversions. Input: A = [1,0,2] Output: true

we record the max value index as maxArr, then we check whether A[i] < A[maxArr[i-2]. class Solution { public: bool isIdealPermutation(vector<int>& A) { int size = A.size(); vector<int> maxArr(size); maxArr[0] = 0; for(int i = 1; i < size; i ++) { if(A[i] > A[maxArr[i-1]]) maxArr[i] = i; else maxArr[i] = maxArr[i-1]; } for(int i = 2; i < size; i ++ ) { if(A[i] < A[maxArr[i-2]]) return false; } return true; } };

718. Maximum Length of Repeated Subarray Given two integer arrays A and B, return the maximum length of an subarray that appears in both arrays. Example 1: Input: A: [1,2,3,2,1] B: [3,2,1,4,7] Output: 3

we use dp[i][j] to indicate the max repeated sub array after i, j. class Solution { public: int findLength(vector<int>& A, vector<int>& B) { int size1 = A.size(); int size2 = B.size(); vector<vector<int>> dp(size1 + 1, vector<int>(size2 + 1)); int res = 0; for(int i = size1 - 1; i >= 0; i --) { for(int j = size2 - 1; j >= 0; j --) { if(A[i] == B[j]) dp[i][j] = dp[i+1][j+1] +1; else dp[i][j] = 0; res = max(res, dp[i][j]); } } return res; } };

907. Sum of Subarray Minimums Given an array of integers A, find the sum of min(B), where B ranges over every (contiguous) subarray of A. Input: [3,1,2,4] Output: 17 Explanation: Subarrays are [3], [1], [2], [4], [3,1], [1,2], [2,4], [3,1,2], [1,2,4], [3,1,2,4].

we use stack to get the min index of left[i] and right[i]. then for index i: curr = A[i] * left[i] count * right[i] count. class Solution { private: int mod = 1e9 + 7; public: int sumSubarrayMins(vector<int>& A) { int size = A.size(); vector<int> left(size); vector<int> right(size); for(int i = 0; i < size; i ++) { left[i] = i; right[i] = i; } stack<int> s; for(int i = 0; i < size; i ++) { while(!s.empty() && A[i] <= A[s.top()]) { right[s.top()] = i; s.pop(); } s.push(i); } stack<int> s1; for(int i = size-1; i >= 0; i --) { while(!s1.empty() && A[i] < A[s1.top()]) { left[s1.top()] = i; s1.pop(); } s1.push(i); } long res = 0; for(int i = 0; i< size; i ++) { long l = left[i] == i? (i + 1): (i - left[i]); long r = right[i] == i? (size - i): (right[i] - i); res = (res + l * r * A[i]) % mod; } return res; } };

922. Sort Array By Parity II Given an array A of non-negative integers, half of the integers in A are odd, and half of the integers are even. Sort the array so that whenever A[i] is odd, i is odd; and whenever A[i] is even, i is even. You may return any answer array that satisfies this condition. Input: [4,2,5,7] Output: [4,5,2,7]

1. we use odd and even array. 2. we keep i index as even index and j from 1 as odd index. class Solution { public: vector<int> sortArrayByParityII(vector<int>& A) { int size = A.size(); int j = 1; for(int i = 0; i < size; i += 2) { if(A[i] % 2 == 1) { while(j < size && A[j] % 2 == 1) j += 2; int tmp = A[i]; A[i] = A[j]; A[j] = tmp; } } return A; } vector<int> sortArrayByParityII1(vector<int>& A) { //use extra odd and even array int size = A.size(); vector<int> even; vector<int> odd; for(auto& num: A) { if(num % 2 ==0) even.push_back(num); else odd.push_back(num); } int ind = 0; for(int i=0; i< size; i+= 2) A[i] = even[ind++]; ind = 0; for(int i = 1; i < size; i += 2) A[i] = odd[ind++]; return A; } };

661. Image Smoother Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoother to make the gray scale of each cell becomes the average gray scale (rounding down) of all the 8 surrounding cells and itself. If a cell has less than 8 surrounding cells, then use as many as you can. Input: [[1,1,1], [1,0,1], [1,1,1]] Output: [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

class Solution { private: vector<vector<int>> delta = {{-1, -1}, {-1,0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; public: vector<vector<int>> imageSmoother(vector<vector<int>>& M) { int rows = M.size(); if(rows == 0) return {}; int cols = M[0].size(); vector<vector<int>> res(rows, vector<int>(cols)); for(int r = 0; r < rows; r ++) { for(int c = 0; c < cols; c ++) { int val = M[r][c]; int cnt = 1; for(auto& arr: delta) { int x = r + arr[0]; int y = c + arr[1]; if(x >= 0 && x < rows && y >= 0 && y < cols) { val += M[x][y]; cnt ++; } } res[r][c] = val / cnt; } } return res; } };

896. Monotonic Array An array is monotonic if it is either monotone increasing or monotone decreasing. An array A is monotone increasing if for all i <= j, A[i] <= A[j]. An array A is monotone decreasing if for all i <= j, A[i] >= A[j]. Return true if and only if the given array A is monotonic. Input: [6,5,4,4] Output: true

class Solution { public: bool isMonotonic(vector<int>& A) { int size = A.size(); if(size < 3) return true; int i = 0; while(i + 1 < size && A[i] == A[i+1]) i ++; if(i == size-1) return true; bool greater = A[i] > A[i+1]; if(greater) { while(i + 1 < size && A[i] >= A[i+1]) i ++; if(i != size-1) return false; return true; } while(i +1 < size && A[i] <= A[i+1]) i ++; if(i != size-1) return false; return true; } };

832. Flipping an Image Given a binary matrix A, we want to flip the image horizontally, then invert it, and return the resulting image. To flip an image horizontally means that each row of the image is reversed. For example, flipping [1, 1, 0] horizontally results in [0, 1, 1]. To invert an image means that each 0 is replaced by 1, and each 1 is replaced by 0. For example, inverting [0, 1, 1] results in [1, 0, 0]. Input: [[1,1,0],[1,0,1],[0,0,0]] Output: [[1,0,0],[0,1,0],[1,1,1]]

class Solution { public: vector<vector<int>> flipAndInvertImage(vector<vector<int>>& A) { int rows = A.size(); if(rows == 0) return {}; int cols = A[0].size(); for(int i = 0; i < rows; i ++) { int l = 0; int r = cols-1; while(l <= r) { int tmp = 1-A[i][l]; A[i][l] = 1-A[i][r]; A[i][r] = tmp; l ++; r --; } } return A; } };

867. Transpose Matrix Given a matrix A, return the transpose of A. The transpose of a matrix is the matrix flipped over it's main diagonal, switching the row and column indices of the matrix. Input: [[1,2,3],[4,5,6]] Output: [[1,4],[2,5],[3,6]]

class Solution { public: vector<vector<int>> transpose(vector<vector<int>>& A) { int rows = A.size(); if(rows == 0) return {}; int cols= A[0].size(); vector<vector<int>> res(cols, vector<int>(rows)); for(int r = 0; r < cols; r ++) { for(int c = 0; c < rows; c ++) { res[r][c] = A[c][r]; } } return res; } };

747. Largest Number At Least Twice of Others In a given integer array nums, there is always exactly one largest element. Find whether the largest element in the array is at least twice as much as every other number in the array. If it is, return the index of the largest element, otherwise return -1. Input: nums = [3, 6, 1, 0] Output: 1

first scan to get the max num index, second scan to check. class Solution { public: int dominantIndex(vector<int>& nums) { int maxInd = 0; for(int i = 1; i < nums.size(); i ++) { if(nums[i] > nums[maxInd]) maxInd = i; } for(int i = 0; i< nums.size(); i ++) if(i != maxInd) { if(nums[maxInd] < nums[i] * 2) return -1; } return maxInd; } };

697. Degree of an Array Given a non-empty array of non-negative integers nums, the degree of this array is defined as the maximum frequency of any one of its elements. Your task is to find the smallest possible length of a (contiguous) subarray of nums, that has the same degree as nums. Input: [1, 2, 2, 3, 1] Output: 2

first use countmap to find the degree. then use l and r two pointers . if counts[r] == degree, move l forward. class Solution { public: int findShortestSubArray(vector<int>& nums) { unordered_map<int,int> counts; int degree = 0; for(auto& num: nums) { counts[num] ++; degree = max(degree, counts[num]); } int res = INT_MAX; int l = 0; unordered_map<int,int> countMap; for(int r = 0; r < nums.size(); r ++) { countMap[nums[r]] ++; if(countMap[nums[r]] == degree) { while(countMap[nums[r]] == degree) { res = min(res, r - l + 1); countMap[nums[l]] --; l ++; } } } return res; } };

870. Advantage Shuffle Given two arrays A and B of equal size, the advantage of A with respect to B is the number of indices i for which A[i] > B[i]. Return any permutation of A that maximizes its advantage with respect to B. Input: A = [2,7,11,15], B = [1,10,4,11] Output: [2,11,7,15]

for each num in B, we find its upper bound in A. class Solution { public: vector<int> advantageCount(vector<int>& A, vector<int>& B) { multiset<int> nums; for(auto& num: A) nums.insert(num); vector<int> res(B.size(), -1); for(int i = 0; i < B.size(); i ++) { auto ite = nums.upper_bound(B[i]); if(ite == nums.end()) continue; res[i] = *ite; nums.erase(ite); } auto ite = nums.begin(); for(int i = 0; i < B.size(); i ++) { if(res[i] == -1) { res[i] = *ite; ++ite; } } return res; } };

667. Beautiful Arrangement II Given two integers n and k, you need to construct a list which contains n different positive integers ranging from 1 to n and obeys the following requirement: Suppose this list is [a1, a2, a3, ... , an], then the list [|a1 - a2|, |a2 - a3|, |a3 - a4|, ... , |an-1 - an|] has exactly k distinct integers. If there are multiple answers, print any of them. Input: n = 3, k = 2 Output: [1, 3, 2]

from num 1, we push 1 + k as next, then for num 2, we push 1 + (k - 2) as next.... until k < 2. class Solution { public: vector<int> constructArray(int n, int k) { vector<bool> used(n+1, false); vector<int> nums; if(k == 1) { for(int i = 1; i <= n; i ++) nums.push_back(i); return nums; } int i = 1; while(i <= n) { if(used[i]) { i ++; continue; } nums.push_back(i); used[i] = true; if(k >= 2) { nums.push_back(i + k); used[i + k] = true; k -= 2; } i ++; } return nums; } };

768. Max Chunks To Make Sorted II Given an array arr of integers (not necessarily distinct), we split the array into some number of "chunks" (partitions), and individually sort each chunk. After concatenating them, the result equals the sorted array. What is the most number of chunks we could have made? Input: arr = [2,1,3,4,4] Output: 4

same as previous #769, but there are duplicates. we use pair(num,count) to indicate one unique num. typedef pair<int,int> pi; struct comparer { bool operator() (const pi& p1, const pi& p2) const { return p1.first < p2.first || (p1.first == p2.first && p1.second < p2.second); } }; class Solution { private: map< pair<int,int>, int> indMap; set<pi, comparer> pairs; public: int maxChunksToSorted(vector<int>& arr) { unordered_map<int, int> counts; for(int i = 0; i < arr.size(); i ++) { counts[arr[i]] ++; pairs.insert( pair(arr[i], counts[arr[i]]) ); } int i = 0; for(auto& pair: pairs) indMap[pair] = i ++; counts.clear(); int maxInd = 0; int res =0; for(int i = 0; i < arr.size(); i ++) { counts[arr[i]] ++; int ind = indMap[pair(arr[i], counts[arr[i]])]; maxInd = max(maxInd, ind); if(i == maxInd) { res ++; maxInd = ind++; } } return res; } };

729. My Calendar I Implement a MyCalendar class to store your events. A new event can be added if adding the event will not cause a double booking. Your class will have the method, book(int start, int end). Formally, this represents a booking on the half open interval [start, end), the range of real numbers x such that start <= x < end.

similar as merge modules. struct Range { int s; int e; Range() {}; Range(int s, int e): s(s), e(e) {}; }; struct comparer { bool operator() (const Range& r1, const Range& r2) const { return r1.e < r2.e || (r1.e == r2.e && r1.s < r2.s); } }; class MyCalendar { private: set<Range, comparer> ranges; public: MyCalendar() { } bool book(int start, int end) { auto ite = ranges.lower_bound(Range(0, start) ); if(ite != ranges.end() && ite-> e == start) ++ite; if(ite == ranges.end() || ite->s >= end) { ranges.insert(Range(start, end)); return true; } return false; } };

905. Sort Array By Parity Given an array A of non-negative integers, return an array consisting of all the even elements of A, followed by all the odd elements of A. Input: [3,1,2,4] Output: [2,4,3,1]

similar to the Polland flag problem, we use l and r pointers to indicate the seperator of even and odd index. class Solution { public: vector<int> sortArrayByParity(vector<int>& A) { int size = A.size(); int l = 0; int r = size-1; int i = 0; while(l <= r) { int val = A[i]; if(val % 2 == 0) { swap(A, i, l); { l ++; i ++; } } else { swap(A, i, r); r --; } } return A; } void swap(vector<int>& A, int i, int j) { int tmp = A[i]; A[i] = A[j]; A[j] = tmp; } };

891. Sum of Subsequence Widths Given an array of integers A, consider all non-empty subsequences of A. For any sequence S, let the width of S be the difference between the maximum and minimum element of S. Return the sum of the widths of all subsequences of A. Input: [2,1,3] Output: 6 Explanation: Subsequences are [1], [2], [3], [2,1], [2,3], [1,3], [2,1,3].

the results keep the same after sorting. the counts of min i, max j is pow(2, j - i - 1); so res is for each i from 0 to size-1, j from i +1 to size-1, add up the counts. after simplify, the result is for i from 0 to size-1, sum of (pow[i] - pos[N- i - 1]) * A[i] class Solution { public: int sumSubseqWidths(vector<int>& A) { //[1,2,3] after sorting A, count of min i max j is: pow(2, j- i -1) (the num in between has or has not) //... after calc, euqals to for each i: (pow(2, i) - pow(2, size-i-1)) * A[i] int mod = 1e9 + 7; sort(A.begin(), A.end()); int size = A.size(); vector<long> powArr(size); powArr[0] = 1; for(int i = 1; i < size; i ++) { powArr[i] = powArr[i-1] * 2 % mod; } long res = 0; for(int i = 0; i < size; i ++) { long num = (powArr[i] - powArr[size-i-1]) * A[i] % mod; res = (res + num) % mod; } return res; } };

840. Magic Squares In Grid A 3 x 3 magic square is a 3 x 3 grid filled with distinct numbers from 1 to 9 such that each row, column, and both diagonals all have the same sum. Given an grid of integers, how many 3 x 3 "magic square" subgrids are there? (Each subgrid is contiguous). Input: [[4,3,8,4], [9,5,1,9], [2,7,6,2]] Output: 1

we check whether 9 number as all exist and sum are same. class Solution { public: int numMagicSquaresInside(vector<vector<int>>& grid) { int rows = grid.size(); if(rows == 0) return 0; int cols = grid[0].size(); if(rows < 3 || cols < 3) return 0; int res = 0; int mask = (1<<9) - 1; for(int r = 0; r +2 < rows; r ++) { for(int c = 0; c + 2 < cols; c ++) { bool valid = true; int val = 0; for(int i = r; i < r + 3; i ++) for(int j = c; j < c +3; j ++) { if(grid[i][j] <= 0) { valid = false; break; } val |= (1 << (grid[i][j] - 1)); } if(val != mask) { valid = false; continue; } for(int i = r; i < r +3; i ++) { if(grid[i][c] + grid[i][c+1] + grid[i][c+2] != 15) { valid = false; break; } } if(!valid) continue; for(int j = c; j < c + 3; j ++) { if(grid[r][j] + grid[r+1][j] + grid[r+2][j] != 15) { valid = false; break; } } if(!valid) continue; if(grid[r][c] + grid[r+1][c+1] + grid[r+2][c+2] != 15) { valid = false; break; } if(!valid) continue; if(grid[r+2][c] + grid[r+1][c+1] + grid[r][c+2] != 15) { valid = false; break; } if(!valid) continue; res ++; } } return res; } };

914. X of a Kind in a Deck of Cards In a deck of cards, each card has an integer written on it. Return true if and only if you can choose X >= 2 such that it is possible to split the entire deck into 1 or more groups of cards, where: Each group has exactly X cards. All the cards in each group have the same integer. Input: [1,2,3,4,4,3,2,1] Output: true

we first get the counts of each card. then get the gcd of first two card count. then iterate the rest card and get gcd of count and d. class Solution { public: bool hasGroupsSizeX(vector<int>& deck) { unordered_map<int,int> counts; for(auto& val: deck) counts[val] ++; if(counts.size() == 1 && counts.begin()->second >= 2) return true; else if(counts.size() == 1) return false; auto ite = counts.begin(); int cnt1 = ite->second; ite ++; int cnt2 = ite->second; int gcd = getgcd(cnt1, cnt2); if(gcd == 1) return false; for(; ite != counts.end(); ite ++) { if(getgcd(ite->second, gcd) == 1) return false; } return true; } int getgcd(int v1, int v2) { if(v1 == 0) return v2; else return getgcd(v2 % v1, v1); } };

873. Length of Longest Fibonacci Subsequence A sequence X_1, X_2, ..., X_n is fibonacci-like if: n >= 3 X_i + X_{i+1} = X_{i+2} for all i + 2 <= n Given a strictly increasing array A of positive integers forming a sequence, find the length of the longest fibonacci-like subsequence of A. If one does not exist, return 0. (Recall that a subsequence is derived from another sequence A by deleting any number of elements (including none) from A, without changing the order of the remaining elements. For example, [3, 5, 8] is a subsequence of [3, 4, 5, 6, 7, 8].) Input: [1,2,3,4,5,6,7,8] Output: 5

we first get the ind map. then we record the map< pair<int,int>, int > counts. map[pair(num1, num2)] = count: means that the fibonacci sequence ended with num1, num2 has count. so map[pair(num1, num2)] = map[pair(num2-num1, num1]) + 1. class Solution { public: int lenLongestFibSubseq(vector<int>& A) { int size = A.size(); if(size < 3) return 0; unordered_map<int,int> indMap; for(int i = 0; i < size ; i ++) indMap[A[i]] = i; map<pair<int,int>, int> counts; int res = 1; for(int i = 1; i < size; i ++) { for(int j = i-1; j >= 0; j --) { int prev = A[i] - A[j]; if(prev < A[j] && indMap.find(prev) != indMap.end()) { counts[pair(A[j], A[i])] = counts[pair(prev, A[j])] + 1; res = max(res, counts[pair(A[j], A[i])] + 2); } } } return res < 3? 0: res; } };

724. Find Pivot Index Given an array of integers nums, write a method that returns the "pivot" index of this array. We define the pivot index as the index where the sum of the numbers to the left of the index is equal to the sum of the numbers to the right of the index. If no such index exists, we should return -1. If there are multiple pivot indexes, you should return the left-most pivot index. nums = [1, 7, 3, 6, 5, 6] Output: 3

we first get the sum array , then iterate the index and find the res. class Solution { public: int pivotIndex(vector<int>& nums) { int size = nums.size(); vector<int> sums(size); for(int i = 0; i < size; i ++) sums[i] = i == 0? nums[i]: (sums[i-1] + nums[i]); int res = -1; for(int i = 0; i < size; i ++) { int l = i ==0? 0: sums[i-1]; int r = sums[size-1] - sums[i]; if(l == r) return i; } return -1; } };

755. Pour Water Water first drops at index K and rests on top of the highest terrain or water at that index. Then, it flows according to the following rules: If the droplet would eventually fall by moving left, then move left. Otherwise, if the droplet would eventually fall by moving right, then move right. Otherwise, rise at it's current position. Input: heights = [2,1,1,2,1,2,2], V = 4, K = 3 Output: [2,2,2,3,2,2,2]

we first iterate left, as long h[l] >= h[l-1], l--; then if h[l] == h[l+1] l ++; then iterate right. class Solution { public: vector<int> pourWater(vector<int>& heights, int V, int K) { int size = heights.size(); while(V > 0) { int l = K; while(l >= 1 && heights[l] >= heights[l-1]) l --; while(l < K && heights[l] == heights[l+1]) l ++; bool drop = false; if(l < K) { drop = true; heights[l] ++; V --; continue; } int r = K; while(r + 1 < size && heights[r] >= heights[r + 1]) r ++; while(r > K && heights[r] == heights[r-1]) r --; if(r > K) { drop = true; heights[r] ++; V --; continue; } heights[K] ++; V--; } return heights; } };

918. Maximum Sum Circular Subarray Given a circular array C of integers represented by A, find the maximum possible sum of a non-empty subarray of C. Here, a circular array means the end of the array connects to the beginning of the array. (Formally, C[i] = A[i] when 0 <= i < A.length, and C[i+A.length] = C[i] when i >= 0.) Also, a subarray may only include each element of the fixed buffer A at most once. (Formally, for a subarray C[i], C[i+1], ..., C[j], there does not exist i <= k1, k2 <= j with k1 % A.length = k2 % A.length.) Input: [5,-3,5] Output: 10

we first the the regular max value. then get the right max sum(continuous sub array): rightMax = max(rightSum[i], rightMax[i+1]). then iterate the left index : res = max(res, leftSum + rightMax[i+1]). class Solution { public: int maxSubarraySumCircular(vector<int>& A) { int size = A.size(); if(size == 0) return 0; vector<int> maxSum(size); maxSum[0] = A[0]; int res = A[0]; for(int i = 1; i < size; i ++) { maxSum[i] = max(A[i], maxSum[i-1] + A[i]); res = max(res, maxSum[i]); } vector<int> rightSum(size); rightSum[size-1] = A[size-1]; vector<int> rightMax(size); rightMax[size-1] = A[size-1]; for(int i = size-2; i >= 0; i --) { rightSum[i] = rightSum[i+1] + A[i]; rightMax[i] = max(rightSum[i], rightMax[i+1]); } int leftSum = 0; for(int i = 0; i + 1 < size; i ++) { leftSum += A[i]; res = max(res, leftSum + rightMax[i+1]); } return res; } };

795. Number of Subarrays with Bounded Maximum We are given an array A of positive integers, and two positive integers L and R (L <= R). Return the number of (contiguous, non-empty) subarrays such that the value of the maximum array element in that subarray is at least L and at most R. A = [2, 1, 4, 3] L = 2 R = 3 Output: 3

we get the count of all sub array <= L-1 and count <= R, the diff is answer. class Solution { public: int numSubarrayBoundedMax(vector<int>& A, int L, int R) { int size = A.size(); int cnt1 = count(A, L-1); int cnt2 = count(A, R); return cnt2 - cnt1; } int count(vector<int>& A, int val) { int cnt = 0; int res = 0; for(auto& num: A) { if(num <= val) { cnt ++; res += cnt; } else cnt = 0; } return res; } };

689. Maximum Sum of 3 Non-Overlapping Subarrays In a given array nums of positive integers, find three non-overlapping subarrays with maximum sum. Each subarray will be of size k, and we want to maximize the sum of all 3*k entries. Return the result as a list of indices representing the starting position of each interval (0-indexed). If there are multiple answers, return the lexicographically smallest one. Input: [1,2,1,2,6,7,5,1], 2 Output: [0, 3, 5]

we get the k segment sum and use left[i] to indicate the left largest sum index, use right[i] to indicate the right largest sum index. then iterate from i = k to i + k-1 + k < size, to get the largest sum. class Solution { private: int k; public: vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int k) { this -> k = k; int size = nums.size() - k + 1; vector<int> sums(size); getsums(nums, sums); vector<int> left(size); vector<int> right(size); right[size-1] = size-1; for(int i = 1; i < size; i ++) { if(sums[i] > sums[left[i-1]]) left[i] = i; else left[i] = left[i-1]; int rightInd = size - i - 1; if(sums[rightInd] >= sums[right[rightInd + 1]]) right[rightInd] = rightInd; else right[rightInd] = right[rightInd + 1]; } vector<int> ans; int maxVal = 0; for(int i = k; i + k-1 + k < nums.size(); i ++) { int l = left[i - k]; int r = right[i + k]; int curr = sums[l] + sums[i] + sums[r]; if(curr > maxVal) { ans = {l, i, r}; maxVal = curr; } } return ans; } void getsums(vector<int>& nums, vector<int>& sums) { int sum = 0; for(int i = 0; i < k ; i++) { sum += nums[i]; } sums[0] = sum; for(int i = k; i < nums.size(); i ++) { sum -= nums[i-k]; sum += nums[i]; sums[i-k+1] = sum; } } };

915. Partition Array into Disjoint Intervals Given an array A, partition it into two (contiguous) subarrays left and right so that: Every element in left is less than or equal to every element in right. left and right are non-empty. left has the smallest possible size. Return the length of left after such a partitioning. It is guaranteed that such a partitioning exists. Input: [5,0,3,8,6] Output: 3

we have two ways: 1 get the index of indMap[pair(num, cnt)] = ind. then when current index == maxInd, return ind. 2. record left[i] as the max index until index i and right[i] as the min index from index i. when a[left[i]] <= a[right[i+1]], means left max always <= right min. typedef pair<int,int> pi; struct comparer { bool operator() (const pi& p1, const pi& p2) const { return p1.first < p2.first || (p1.first == p2.first && p1.second < p2.second); } }; class Solution { public: int partitionDisjoint(vector<int>& A) { int size = A.size(); vector<int> left(size); vector<int> right(size); left[0] = 0; right[size-1] = size-1; for(int i = 1; i < size; i ++) { left[i] = A[i] > A[left[i-1]] ? i: left[i-1]; } for(int i = size-2; i >= 0; i --) { right[i] = A[i] < A[right[i+1]]? i: right[i+1]; } for(int i = 0; i+1< size; i ++) { if(A[left[i]] <= A[right[i+1]]) return i+1; } return -1; } int partitionDisjoint1(vector<int>& A) { //use inds int size = A.size(); set<pi, comparer> pairs; unordered_map<int, int> counts; for(int i = 0; i< size; i ++) { counts[A[i]] ++; pairs.insert(pair(A[i], counts[A[i]]) ); } map<pi, int> indMap; int i = 0; for(auto& pair: pairs) indMap[pair] = i++; counts.clear(); int maxInd = 0; for(int i = 0; i < size; i ++) { counts[A[i]] ++; maxInd = max(maxInd, indMap[pair(A[i], counts[A[i]])]); if(maxInd == i) return i + 1; } return -1; } };

670. Maximum Swap Given a non-negative integer, you could swap two digits at most once to get the maximum valued number. Return the maximum valued number you could get. Input: 2736 Output: 7236

we iterate each char i in string and then from i+1 to len, iterate the next char. class Solution { public: int maximumSwap(int num) { string s = to_string(num); int len = s.length(); for(int i = 0; i < len; i ++) { int maxId = i; for(int j = i + 1; j < len ;j ++) { if(s[j] >= s[maxId]) { maxId = j; } } if(s[maxId] != s[i]) { swap(s[maxId], s[i]); break; } } return stoi(s); } };

849. Maximize Distance to Closest Person In a row of seats, 1 represents a person sitting in that seat, and 0 represents that the seat is empty. There is at least one empty seat, and at least one person sitting. Alex wants to sit in the seat such that the distance between him and the closest person to him is maximized. Return that maximum distance to closest person. Input: [1,0,0,0,1,0,1] Output: 2

we iterate the array, if current value is 1, then check the prev index and get dist. class Solution { public: int maxDistToClosest(vector<int>& seats) { int size = seats.size(); if(size == 0) return 0; int maxDist = 0; int ind = -1; int prev = -1; for(int r = 0; r < seats.size(); r ++) { if(seats[r] ==1) { int dis = prev == -1? (r - prev -1): ((r - prev) / 2); if(dis > maxDist) { maxDist = dis; ind = prev == -1? 0: prev + dis; } prev = r; } } if(seats[size-1] == 0) { int dis = size - prev-1; if(dis > maxDist) { maxDist = dis; ind = size-1; } } return maxDist; } };

766. Toeplitz Matrix A matrix is Toeplitz if every diagonal from top-left to bottom-right has the same element. Now given an M x N matrix, return True if and only if the matrix is Toeplitz. matrix = [ [1,2,3,4], [5,1,2,3], [9,5,1,2] ] Output: True

we iterate the first row and first column. class Solution { private: int rows; int cols; public: bool isToeplitzMatrix(vector<vector<int>>& matrix) { rows = matrix.size(); if(rows == 0) return true; cols = matrix[0].size(); for(int r = 0; r < rows; r ++) { if(!valid(r, 0, matrix)) return false; } for(int c = 1; c < cols ;c ++) { if(!valid(0, c, matrix)) return false; } return true; } bool valid(int row, int col, vector<vector<int>>& matrix) { int val = matrix[row][col]; while(true) { row ++; col ++; if(row >= rows || col >= cols) break; if(matrix[row][col] != val) return false; } return true; } };

830. Positions of Large Groups For example, a string like S = "abbxxxxzyy" has the groups "a", "bb", "xxxx", "z" and "yy". Call a group large if it has 3 or more characters. We would like the starting and ending positions of every large group. The final answer should be in lexicographic order. Input: "abbxxxxzzy" Output: [[3,6]]

we keep adding the count if str[r] == str[r-1], else count = 1. class Solution { public: vector<vector<int>> largeGroupPositions(string str) { vector<vector<int>> res; int len = str.length(); int count = 1; for(int r = 1; r < len; r ++) { if(str[r] == str[r-1]) count ++; else { if(count >= 3) res.push_back({ r - count, r -1 }); count = 1; } } if(count >= 3) res.push_back({ len-count, len-1 }); return res; } };

723. Candy Crush If three or more candies of the same type are adjacent vertically or horizontally, "crush" them all at the same time - these positions become empty. After crushing all candies simultaneously, if an empty space on the board has candies on top of itself, then these candies will drop until they hit a candy or bottom at the same time. (No new candies will drop outside the top boundary.) After the above steps, there may exist more candies that can be crushed. If so, you need to repeat the above steps. If there does not exist more candies that can be crushed (ie. the board is stable), then return the current board.

we keep flag[i][j] to indicate whether pos (i, j) should crush or not. then use two pointers to do the cursh. class Solution { private: int rows; int cols; vector<vector<int>> delta = {{-1, 0}, {1, 0}, {0, -1}, {0,1}}; public: vector<vector<int>> candyCrush(vector<vector<int>>& board) { rows = board.size(); if(rows == 0) return {}; cols = board[0].size(); while(true) { int count = 0; vector<vector<bool>> flag(rows, vector<bool>(cols,false)); for(int r = 0; r < rows ;r ++) { for(int c= 0; c < cols;c ++) { if(board[r][c] == 0) continue; if(r +2 < rows && board[r][c] == board[r+1][c] && board[r+1][c] == board[r+2][c]) { flag[r][c] = true; flag[r+1][c] = true; flag[r+2][c] = true; int i = r+3; while(i < rows && board[i][c] == board[r][c]) { flag[i][c] = true; i ++; } count ++; } if(c + 2 < cols && board[r][c] == board[r][c+1] && board[r][c+1] == board[r][c+2]) { flag[r][c] = true; flag[r][c+1] = true; flag[r][c+2] = true; int j = c +3; while(j < cols && board[r][j] == board[r][c]) { flag[r][j] = true; j ++; } count ++; } } } if(count == 0) break; crush(board, flag); } return board; } void crush(vector<vector<int>>& board, vector<vector<bool>>& flag) { for(int c = 0; c < cols; c ++) { int l = rows -1; for(int r = rows-1; r >= 0; r --) { if(!flag[r][c]) { board[l][c] = board[r][c]; l --; } } for(; l >= 0; l --) { board[l][c] = 0; } } } };

835. Image Overlap Two images A and B are given, represented as binary, square matrices of the same size. (A binary matrix has only 0s and 1s as values.) We translate one image however we choose (sliding it left, right, up, or down any number of units), and place it on top of the other image. After, the overlap of this translation is the number of positions that have a 1 in both images. (Note also that a translation does not include any kind of rotation.) What is the largest possible overlap? Input: A = [[1,1,0], [0,1,0], [0,1,0]] B = [[0,0,0], [0,1,1], [0,0,1]] Output: 3

we move A / B to right or down. class Solution { private: int rows; int cols; public: int largestOverlap(vector<vector<int>>& A, vector<vector<int>>& B) { rows = A.size(); if(rows == 0) return 0; cols = A[0].size(); int res = 0; for(int dx = 0; dx < rows; dx ++) { for(int dy = 0; dy < cols; dy ++) { int count = getCount(A, dx, dy, B); res = max(res, count); } } for(int dx = 0; dx < rows; dx ++) { for(int dy = 0; dy <cols; dy ++) { int count = getCount(B, dx, dy, A); res = max(res, count); } } return res; } int getCount(vector<vector<int>>& A, int dx, int dy, vector<vector<int>>& B) { int count = 0; for(int r = 0; r + dx < rows; r ++) { for(int c = 0; c + dy < cols; c ++) { count += A[r][c] * B[r + dx][c + dy]; } } return count; } };

792. Number of Matching Subsequences Given string S and a dictionary of words words, find the number of words[i] that is a subsequence of S. S = "abcde" words = ["a", "bb", "acd", "ace"] Output: 3

we record next[i][j] as the next index after current index i of char j. then for each word, we iterate each char and find next index. class Solution { public: int numMatchingSubseq(string str, vector<string>& words) { int res = 0; int len = str.length(); vector<vector<int>> next(len, vector<int>(26, -1)); vector<int> inds(26, -1); for(int i = len-1; i >= 0; i --) { inds[str[i] - 'a'] = i; for(int j = 0; j < 26; j++) { next[i][j] = inds[j]; } } for(auto& s: words) { if(sub(str, s, next)) res ++; } return res; } bool sub(string str, string s, vector<vector<int>>& next) { int r = 0; for(int i = 0; i < s.length(); i ++) { if(r >= str.length()) return false; int ind = next[r][s[i] - 'a']; if(ind == -1) return false; r = ind+1; } return true; } };

945. Minimum Increment to Make Array Unique Given an array of integers A, a move consists of choosing any A[i], and incrementing it by 1. Return the least number of moves to make every value in A unique. Input: [3,2,1,2,1,7] Output: 6

we record sum1 as the duplicates needs to move. we record sum2 as the target sum after the move. result is sum2 - sum1. class Solution { public: int minIncrementForUnique(vector<int>& A) { int size = A.size(); sort(A.begin(), A.end()); int sum1 = 0; int sum2 = 0; int dups = 0; for(int i = 1; i < size ; i++) { if(A[i] == A[i-1]) { dups ++; sum1 += A[i]; } else if(A[i] - A[i-1] > 1) { int gap = A[i] - A[i-1] -1; int cnt = min(dups, gap); sum2 += (A[i-1] + 1 + A[i-1] + cnt) * cnt / 2; dups -= cnt; } } if(dups > 0) { int end = A.back(); sum2 += (end + 1 + end + dups) * dups / 2; } return sum2 - sum1; } };

900. RLE Iterator Write an iterator that iterates through a run-length encoded sequence. The iterator is initialized by RLEIterator(int[] A), where A is a run-length encoding of some sequence. More specifically, for all even i, A[i] tells us the number of times that the non-negative integer value A[i+1] is repeated in the sequence. The iterator supports one function: next(int n), which exhausts the next n elements (n >= 1) and returns the last element exhausted in this way. If there is no element left to exhaust, next returns -1 instead. Input: ["RLEIterator","next","next","next","next"], [[[3,8,0,9,2,5]],[2],[1],[1],[2]] Output: [null,8,8,5,-1]

we record the array, the index and also used count. class RLEIterator { private: vector<int> arr; int ind = 0; int count = 0; public: RLEIterator(vector<int>& A) { arr = A; } int next(int n) { skip(); if(ind >= arr.size()) return -1; if(n + count <= arr[ind]) { count += n; return arr[ind+1]; } n = n + count - arr[ind]; count = 0; ind += 2; while(ind < arr.size() && n > arr[ind]) { n -= arr[ind]; ind += 2; } if(ind >= arr.size() ) return -1; count += n; return arr[ind+1]; } void skip() { while(ind < arr.size() && count >= arr[ind]) { ind += 2; count = 0; } } }; /** * Your RLEIterator object will be instantiated and called as such: * RLEIterator* obj = new RLEIterator(A); * int param_1 = obj->next(n); */

674. Longest Continuous Increasing Subsequence Given an unsorted array of integers, find the length of longest continuous increasing subsequence (subarray). Input: [1,3,5,4,7] Output: 3

we record the count at each index. class Solution { public: int findLengthOfLCIS(vector<int>& nums) { int size = nums.size(); if(size == 0) return 0; vector<int> counts(size); int res = 1; counts[0] = 1; for(int i = 1; i < size; i ++) { if(nums[i] > nums[i-1]) { counts[i] = counts[i-1] + 1; res = max(res, counts[i]); } else counts[i] = 1; } return res; } };

926. Flip String to Monotone Increasing A string of '0's and '1's is monotone increasing if it consists of some number of '0's (possibly 0), followed by some number of '1's (also possibly 0.) We are given a string S of '0's and '1's, and we may flip any '0' to a '1' or a '1' to a '0'. Return the minimum number of flips to make S monotone increasing. Input: "010110" Output: 2

we record the count of "0" and "1" until current index i, and dp[i] is the min flip until index i to make string valid. if current char is a '1', dp[i] = dp[i-1]; else if current char is a '0', we can either flip all the previous '1' (counts['1']) or flip current '0'. so dp[i] = min(counts['1'], dp[i-1] + 1). class Solution { public: int minFlipsMonoIncr(string str) { int len = str.length(); if(len == 0) return 0; unordered_map<char, int> counts; vector<int> dp(len); dp[0] = 0; counts[str[0]] ++; for(int i = 1; i < len; i ++) { counts[str[i]] ++; if(str[i] == '1') { dp[i] = dp[i-1]; } else { dp[i] = min(dp[i-1] + 1, counts['1']); } } return dp[len-1]; } };

769. Max Chunks To Make Sorted Given an array arr that is a permutation of [0, 1, ..., arr.length - 1], we split the array into some number of "chunks" (partitions), and individually sort each chunk. After concatenating them, the result equals the sorted array. What is the most number of chunks we could have made? Input: arr = [1,0,2,3,4] Output: 4

we record the maxInd needed to make the array sorted. if(i == maxInd) res ++ , maxInd = i +1. class Solution { public: int maxChunksToSorted(vector<int>& arr) { int res = 0; int maxInd = 0; for(int i = 0; i < arr.size(); i ++) { maxInd = max(maxInd, arr[i]); if(i == maxInd) { res ++; maxInd = i +1; } } return res; } };

950. Reveal Cards In Increasing Order In a deck of cards, every card has a unique integer. You can order the deck in any order you want. Initially, all the cards start face down (unrevealed) in one deck. Now, you do the following steps repeatedly, until all cards are revealed: Take the top card of the deck, reveal it, and take it out of the deck. If there are still cards in the deck, put the next top card of the deck at the bottom of the deck. If there are still unrevealed cards, go back to step 1. Otherwise, stop. Return an ordering of the deck that would reveal the cards in increasing order. The first entry in the answer is considered to be the top of the deck. Input: [17,13,11,2,3,5,7] Output: [2,13,3,11,5,17,7]

we sort the deck. if size < 3, return deck. final 2 deck are already valid state. from size-3, we reverse the steps: res[i] = deck[i], res.pop_back(), res.insert(res.begin() + i + 1, back); class Solution { public: vector<int> deckRevealedIncreasing(vector<int>& deck) { int size = deck.size(); sort(deck.begin(), deck.end()); if(size < 3) return deck; vector<int> res(size); res[size-2] = deck[size-2]; res[size-1] = deck[size-1]; for(int i = size-3; i >= 0; i --) { int back = res.back(); res[i] = deck[i]; res.pop_back(); res.insert(res.begin() + i + 1, back); } return res; } };

719. Find K-th Smallest Pair Distance Given an integer array, return the k-th smallest distance among all the pairs. The distance of a pair (A, B) is defined as the absolute difference between A and B. nums = [1,3,1] k = 1

we use binary search to get the next distance val, then use two pointers to get the number of distance <= val. class Solution { public: int smallestDistancePair(vector<int>& nums, int k) { int size = nums.size(); sort(nums.begin(), nums.end()); int maxV = INT_MIN; for(int i = 0; i < size; i ++) { maxV = max(maxV, nums[i]); } int l = 0; int r = maxV; while(l < r) { int mid = (l + r) / 2; if(count(nums, mid) < k) l = mid + 1; else r = mid; } return l; } int count(vector<int>& nums, int val) { int l = 0; int res = 0; for(int r = 0; r < nums.size(); r ++) { while(nums[r] - nums[l] > val) { l ++; } res += r - l; } return res; } };

714. Best Time to Buy and Sell Stock with Transaction Fee Your are given an array of integers prices, for which the i-th element is the price of a given stock on day i; and a non-negative integer fee representing a transaction fee. You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction. You may not buy more than 1 share of a stock at a time (ie. you must sell the stock share before you buy again.) Return the maximum profit you can make. Input: prices = [1, 3, 2, 8, 4, 9], fee = 2 Output: 8

we use buy[i] to indicate the max money I have after I buy at day i, sell[i] inidcate the max money I have after sell at day i. class Solution { public: int maxProfit(vector<int>& prices, int fee) { int size = prices.size(); vector<int> buy(size + 1); vector<int> sell(size +1); buy[0] = INT_MIN; sell[0] = 0; for(int i = 1; i <= size; i ++) { buy[i] = max(buy[i-1], sell[i-1] - prices[i-1]); sell[i] = max(sell[i-1], buy[i] + prices[i-1] - fee); } return max(buy[size], sell[size]); } };

954. Array of Doubled Pairs Given an array of integers A with even length, return true if and only if it is possible to reorder it such that A[2 * i + 1] = 2 * A[2 * i] for every 0 <= i < len(A) / 2. Input: [4,-2,2,-4] Output: true

we use map to record the counts. class Solution { public: bool canReorderDoubled(vector<int>& A) { int size = A.size(); map<int,int> counts; for(auto& num: A) counts[num] ++; int pair = 0; for(auto& [num, cnt]: counts) if(cnt > 0) { if(num == 0) { pair += cnt / 2; continue; } if(counts.find(num * 2) != counts.end() ) { int curr = min(cnt, counts[num * 2]); pair += curr; counts[num] -= curr; counts[num * 2] -= curr; } } return pair == size / 2; } };

665. Non-decreasing Array Given an array with n integers, your task is to check if it could become non-decreasing by modifying at most 1 element. We define an array is non-decreasing if array[i] <= array[i + 1] holds for every i (1 <= i < n). Input: [2,3,3,2,4] Output: True

we use stack to record the nums. if current num < stack top, then record the current count. two case: 1. there are more than 1 top that > current num, then we can modify current num to the first top value. 2. there is one top that > current value, then we modify that top value. class Solution { public: bool checkPossibility(vector<int>& nums) { int cnt = 0; stack<int> s; for(auto& num: nums) { int top = num; int count = 0; while(!s.empty() && num < s.top()) { if(top == num) top = s.top(); count ++; s.pop(); } if(count > 1) { s.push(top); count = 1; } else s.push(num); cnt += count; } return cnt <= 1; } };

713. Subarray Product Less Than K Your are given an array of positive integers nums. Count and print the number of (contiguous) subarrays where the product of all the elements in the subarray is less than k. Input: nums = [10, 5, 2, 6], k = 100 Output: 8

we use two pointers, if current prod >= k, move l forward while l <= r. class Solution { public: int numSubarrayProductLessThanK(vector<int>& nums, int k) { if(k == 0) return 0; int size = nums.size(); int res = 0; int l = 0; int prod = 1; for(int r = 0; r < size; r ++) { prod *= nums[r]; while(l <= r && prod >= k) { prod /= nums[l]; l ++; } res += (r - l + 1); } return res; } };

825. Friends Of Appropriate Ages Some people will make friend requests. The list of their ages is given and ages[i] is the age of the ith person. Person A will NOT friend request person B (B != A) if any of the following conditions are true: age[B] <= 0.5 * age[A] + 7 age[B] > age[A] age[B] > 100 && age[A] < 100 Input: [16,16] Output: 2

we use vector<int> (121) to record the age counts. for age we add up from 0.5 * age +7 + 1 to age. class Solution { public: int numFriendRequests(vector<int>& ages) { int size = ages.size(); vector<int> counts(121); for(auto& num: ages) counts[num] ++; int res = 0; for(int i = 1; i <= 120; i ++) { int val = 0.5 * i + 7 + 1; if(val > i) continue; for(int j = val; j <= i; j ++) { res += (counts[j] * counts[i]); } res -= counts[i]; } return res; } };

717. 1-bit and 2-bit Characters We have two special characters. The first character can be represented by one bit 0. The second character can be represented by two bits (10 or 11). Now given a string represented by several bits. Return whether the last character must be a one-bit character or not. The given string will always end with a zero. bits = [1, 1, 1, 0] Output: False

when i bit is 1, i += 2, else i ++. if i is size-2 and bit is 1, return false; if if is size-1, true. class Solution { public: bool isOneBitCharacter(vector<int>& bits) { int size = bits.size(); for(int i = 0; i < size; ) { if(i == size-2 && bits[i] == 1) return false; else if(i == size-1) return true; else if(bits[i] == 1) i += 2; else i ++; } return true; } };


Conjuntos de estudio relacionados

Human Sexuality exam 1 Chap(1,4,5,6)

View Set

CNA 101 | Ch. 10 Application Layer

View Set

intro to finance chapter 3 problems

View Set

Chapter 44: Introduction to the Gastrointestinal System and Accessory Structures

View Set

Hearing, balance, taste, and smell

View Set

Microeconomics - Perfect Competition

View Set