Stack
最大蓄水问题
11. Container With Most Water
Approach 1 : Brute Force
class Solution {
public int maxArea(int[] height) {
int len = height.length;
int maximumArea = 0;
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {
maximumArea = Math.max(maximumArea, (j - i) * Math.min(height[i], height[j]));
}
}
return maximumArea;
}
}
Approach 2 : Two Pointer
class Solution {
public int maxArea(int[] height) {
int len = height.length;
int maximumArea = 0, l = 0, r = len - 1;
while(l < r){
maximumArea = Math.max(maximumArea, Math.min(height[l], height[r]) * (r - l));
if(height[l] < height[r])
l++;
else
r--;
}
return maximumArea;
}
public static void main(String[] args) {
Solution s = new Solution();
int res = s.maxArea(new int[]{1, 8, 6, 2, 5, 4, 8, 3, 7});
System.out.println(res);
}
}
238. Product of Array Except Self
Approach 1 : Left and Right product lists
class Solution {
public int[] productExceptSelf(int[] nums) {
int len = nums.length;
int[] leftProduct = new int[len];
int[] rightProduct = new int[len];
Arrays.fill(leftProduct, 1);
Arrays.fill(rightProduct, 1);
for (int i = 0; i + 1 < len; i++) {
leftProduct[i + 1] = leftProduct[i] * nums[i];
}
for (int j = len - 1; j > 0; j--) {
rightProduct[j - 1] = rightProduct[j] * nums[j];
}
int[] res = new int[len];
for (int i = 0; i < len; i++) {
res[i] = leftProduct[i] * rightProduct[i];
}
return res;
}
}
Approach 2 : O(1) space approach
class Solution {
public int[] productExceptSelf(int[] nums) {
int len = nums.length;
int[] res = new int[len];
Arrays.fill(res, 1);
for (int i = 0; i + 1 < len; i++) {
res[i + 1] = res[i] * nums[i];
}
int product = nums[len - 1];
for (int j = len - 2; j >= 0; j--) {
res[j] = res[j] * product;
product = product * nums[j];
}
return res;
}
}
42. Trapping Rain Water
Approach 1 : Brute force
class Solution {
public int trap(int[] height) {
int ans = 0, n = height.length;
int left_max, right_max;
for (int i = 0; i < n; i++) {
left_max = 0;
right_max = 0;
for (int j = 0; j < i; j++) {
left_max = Math.max(left_max, height[j]);
}
for (int j = i + 1; j < n; j++) {
right_max = Math.max(right_max, height[j]);
}
int min = Math.min(left_max, right_max);
if(min != 0 && min > height[i]){
ans += min - height[i];
}
}
return ans;
}
}
Approach 2 : Dynamic Programming
class Solution {
public int trap(int[] height) {
int n = height.length;
if(n == 0)
return 0;
int[] left = new int[n], right = new int[n];
left[0] = Integer.MIN_VALUE;
for (int i = 1; i < n; i++) {
left[i] = Math.max(left[i - 1], height[i - 1]);
}
right[n - 1] = Integer.MIN_VALUE;
for (int j = n - 2; j >= 0; j--) {
right[j] = Math.max(right[j + 1], height[j + 1]);
}
int res = 0;
for (int i = 0; i < n; i++) {
int h = Math.min(left[i], right[i]);
if(h != Integer.MIN_VALUE && h > height[i]){
res += h - height[i];
}
}
return res;
}
}
Approach 3 : Using Stack
class Solution {
public int trap(int[] height) {
int ans = 0, current = 0;
Stack<Integer> st = new Stack();
while(current < height.length){
while(!st.empty() && height[current] > height[st.peek()]){
int top = st.pop();
if(st.empty())
break;
int distance = current - st.peek() - 1;
int bounded_height = Math.min(height[current], height[st.peek()]) - height[top];
ans += distance * bounded_height;
}
st.push(current++);
}
return ans;
}
}
Approach 4 : Two Pointers
class Solution {
public int trap(int[] height) {
int left = 0, right = height.length - 1;
int ans = 0;
int leftMax = 0, rightMax = 0;
while(left < right){
if(height[left] < height[right]){
if (height[left] >= leftMax) {
leftMax = height[left];
} else {
ans += (leftMax - height[left]);
}
++left;
}else{
if(height[right] >= rightMax){
rightMax = height[right];
}else{
ans += (rightMax - height[right]);
}
right--;
}
}
return ans;
}
}
最大矩形面积
221. Maximal Square
class Solution {
public int maximalSquare(char[][] matrix) {
int res = 0;
int m = matrix.length, n = matrix[0].length;
int[][] dp = new int[m][n];
for (int i = 0; i < m; i++) {
dp[i][0] = matrix[i][0] == '1' ? 1 : 0;
if(res == 0 && dp[i][0] == 1)
res = 1;
}
for (int j = 0; j < n; j++) {
dp[0][j] = matrix[0][j] == '1' ? 1 : 0;
if(res == 0 && dp[0][j] == 1)
res = 1;
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if(matrix[i][j] != '0'){
dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
res = Math.max(res, dp[i][j]);
}
}
}
return res * res;
}
}
85. Maximal Rectangle
class Solution {
public int maximalRectangle(char[][] matrix) {
if(matrix == null || matrix.length == 0){
return 0;
}
int rLen = matrix.length, cLen = matrix[0].length;
int[] h = new int[cLen + 1];
int max = 0;
for (int row = 0; row < rLen; row++) {
Stack<Integer> s = new Stack<>();
s.push(-1);
for (int i = 0; i <= cLen; i++) {
if(i < cLen && matrix[row][i] == '1'){
h[i] += 1;
}else
h[i] = 0;
while(s.peek() != -1 && h[i] < h[s.peek()]){
max = Math.max(max, h[s.pop()] * (i - s.peek() - 1));
}
s.push(i);
}
}
return max;
}
}
84. Largest Rectangle in Histogram
算法思想,在栈中保持升序高度的索引,遇到比当前高度矮的进行处理
class Solution {
public int largestRectangleArea(int[] heights) {
int n = heights.length;
Stack<Integer> s = new Stack<>();
int maxArea = 0;
for (int i = 0; i <= n; i++) {
int h = (i == n ? 0 : heights[i]);
if(s.isEmpty() || h >= heights[s.peek()]){
s.push(i);
}else{
int tp = s.pop();
maxArea = Math.max(maxArea, heights[tp] * (s.isEmpty() ? i : i - 1 - s.peek()));
i--;
}
}
return maxArea;
}
}
二叉树遍历
94. Binary Tree Inorder Traversal
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
Stack<TreeNode> st = new Stack<>();
if(root != null)
st.push(root);
List<Integer> res = new ArrayList<>();
while(!st.isEmpty()){
TreeNode node = st.pop();
if(node.left == null && node.right == null){
res.add(node.val);
}else{
if(node.right != null){
st.push(node.right);
node.right = null;
}
st.push(node);
if(node.left != null){
st.push(node.left);
node.left = null;
}
}
}
return res;
}
}
144. Binary Tree Preorder Traversal
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Stack<TreeNode> st = new Stack<>();
if(root != null)
st.push(root);
while(!st.isEmpty()){
TreeNode node = st.pop();
res.add(node.val);
if(node.right != null){
st.push(node.right);
}
if(node.left != null){
st.push(node.left);
}
}
return res;
}
}
145. Binary Tree Postorder Traversal
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Stack<TreeNode> st = new Stack<>();
if(root != null)
st.push(root);
while(!st.isEmpty()){
TreeNode node = st.pop();
if(node.left == null && node.right == null){
res.add(node.val);
}else{
st.push(node);
if(node.right != null){
st.push(node.right);
node.right = null;
}
if(node.left != null){
st.push(node.left);
node.left = null;
}
}
}
return res;
}
}
103. Binary Tree Zigzag Level Order Traversal
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
Stack<TreeNode> st = new Stack<>();
if(root == null)
return res;
boolean leftToRight = true;
st.push(root);
while(!st.isEmpty()){
Stack<TreeNode> next = new Stack<>();
List<Integer> tmp = new ArrayList<>();
while(!st.isEmpty()){
TreeNode node = st.pop();
tmp.add(node.val);
if(leftToRight) {
if (node.left != null) {
next.push(node.left);
}
if (node.right != null) {
next.push(node.right);
}
}else{
if (node.right != null) {
next.push(node.right);
}
if (node.left != null) {
next.push(node.left);
}
}
}
st = next;
res.add(tmp);
leftToRight = !leftToRight;
}
return res;
}
}
表达式计算
227. Basic Calculator II
Approach 1 :Using Stack
class Solution {
public int calculate(String s) {
if(s == null || s.isEmpty())
return 0;
int length = s.length();
Stack<Integer> stack = new Stack<>();
int currentNumber = 0;
char operation = '+';
for (int i = 0; i < length; i++) {
char currentChar = s.charAt(i);
if (Character.isDigit(currentChar)) {
currentNumber = (currentNumber * 10) + (currentChar - '0');
}
if ((!Character.isDigit(currentChar) && Character.isWhitespace(currentChar)) || i == length - 1) {
switch (operation) {
case '-':
stack.push(-currentNumber);
break;
case '+':
stack.push(currentNumber);
break;
case '*':
stack.push(stack.pop() * currentNumber);
break;
case '/':
stack.push(stack.pop() / currentNumber);
break;
default:
break;
}
operation = currentChar;
currentNumber = 0;
}
}
int result = 0;
while(!stack.isEmpty()){
result += stack.pop();
}
return result;
}
}
Approach 2: Optimised Approach without the stack
class Solution {
public int calculate(String s) {
if(s == null || s.isEmpty())
return 0;
int length = s.length();
int currentNumber = 0, lastNumber = 0, result = 0;
char operation = '+';
for (int i = 0; i < length; i++) {
char currentChar = s.charAt(i);
if(Character.isDigit(currentChar)){
currentNumber = (currentNumber * 10) + (currentChar - '0');
}
if((!Character.isDigit(currentChar) && !Character.isWhitespace(currentChar)) || i == length - 1){
if(operation == '+' || operation == '-'){
result += lastNumber;
lastNumber = (operation == '+') ? currentNumber : -currentNumber;
}else if(operation == '*'){
lastNumber = lastNumber * currentNumber;
}else if(operation == '/'){
lastNumber = lastNumber / currentNumber;
}
operation = currentChar;
currentNumber = 0;
}
}
result += lastNumber;
return result;
}
}
224. Basic Calculator
Approach 1: Stack and String Reversal
import java.util.Stack;
class Solution {
public int calculate(String s) {
int operand = 0;
int n = 0;
Stack<Object> stack = new Stack<>();
for (int i = s.length() - 1; i >= 0 ; i--) {
char ch = s.charAt(i);
if(Character.isDigit(ch)){
operand = (int)Math.pow(10, n) * (int)(ch - '0') + operand;
n++;
}else if(ch != ' '){
if(n != 0){
stack.push(operand);
n = 0;
operand = 0;
}
if(ch == '('){
int res = evaluateExpr(stack);
stack.pop();
stack.push(res);
}else {
stack.push(ch);
}
}
}
if(n != 0){
stack.push(operand);
}
return evaluateExpr(stack);
}
private int evaluateExpr(Stack<Object> stack){
int res = 0;
if(!stack.empty()){
if(stack.peek() instanceof Integer)
res = (int)stack.pop();
else{
res = ((char)stack.pop() == '+' ? 1 : -1) * (int)stack.pop();
}
}
while(!stack.empty() && !((char)stack.peek() == ')')){
char sign = (char)stack.pop();
if(sign == '+'){
res += (int)stack.pop();
}else{
res -= (int)stack.pop();
}
}
return res;
}
}
移除重复的字符
316. Remove Duplicate Letters
class Solution {
public String removeDuplicateLetters(String s) {
int len = s.length();
int[] lastIndex = new int[26];
boolean[] seen = new boolean[26];
for (int i = 0; i < len; i++) {
lastIndex[s.charAt(i) - 'a'] = i;
}
Stack<Integer> st = new Stack<>();
for (int i = 0; i < len; i++) {
int index = s.charAt(i) - 'a';
if(seen[index])
continue;
while(!st.isEmpty() && st.peek() > index && i < lastIndex[st.peek()]){
seen[st.pop()] = false;
}
st.push(index);
seen[index] = true;
}
StringBuilder builder = new StringBuilder();
for(int index : st){
builder.append((char)(index + 'a'));
}
return builder.toString();
}
}
判断先序遍历的有效性
331. Verify Preorder Serialization of a Binary Tree
Approach 1 : Using Stack
class Solution {
public boolean isValidSerialization(String preorder) {
Stack<String> st = new Stack<>();
String[] strs = preorder.split(",");
for (int i = 0; i < strs.length; i++) {
String str = strs[i];
while (str.equals("#") && !st.isEmpty() && st.peek().equals("#")) {
st.pop();
if (st.isEmpty()) {
return false;
} else {
st.pop();
}
st.push(str);
}
}
return st.size() == 1 && st.peek().equals("#");
}
}
Approach 2 : 7 lines Easy Java Solution
public boolean isValidSerialization(String preorder) {
String[] nodes = preorder.split(",");
int diff = 1;
for (String node: nodes) {
if (--diff < 0) return false;
if (!node.equals("#")) diff += 2;
}
return diff == 0;
}
处理网状问题
341. Flatten Nested List Iterator
public class NestedIterator implements Iterator<Integer> {
private List<Integer> list = new ArrayList<>();
private int next, size;
public NestedIterator(List<NestedInteger> nestedList) {
Stack<NestedInteger> st = new Stack<>();
for (int i = nestedList.size() - 1; i >= 0 ; i--) {
st.push(nestedList.get(i));
}
while(!st.isEmpty()){
NestedInteger current = st.pop();
if(current.isInteger()){
list.add(current.getInteger());
}else{
List<NestedInteger> nestedIntegers = current.getList();
for (int i = nestedIntegers.size() - 1; i >= 0; i--) {
st.push(nestedIntegers.get(i));
}
}
}
size = list.size();
}
@Override
public Integer next() {
return list.get(next++);
}
@Override
public boolean hasNext() {
return next < size;
}
}
385. Mini Parser
class Solution {
public NestedInteger deserialize(String s) {
Stack<Object> st = new Stack<>();
int start = 0, i;
for (i = 0; i < s.length(); i++) {
char currentChar = s.charAt(i);
if(currentChar == '['){
st.push(currentChar);
start = i + 1;
}else if(currentChar == ','){
if(start != i){
int value = Integer.parseInt(s.substring(start, i));
st.push(new NestedInteger(value));
}
start = i + 1;
}else if(currentChar == ']'){
if(start != i){
int value = Integer.parseInt(s.substring(start, i));
st.push(new NestedInteger(value));
}
NestedInteger cur = new NestedInteger();
List<NestedInteger> list = new ArrayList<>();
while(!st.isEmpty() && !(st.peek() instanceof Character)){
list.add(0, (NestedInteger)st.pop());
}
for (NestedInteger ni : list) {
cur.add(ni);
}
st.pop();
st.push(cur);
start = i + 1;
}else
;
}
if(start != i){
int value = Integer.parseInt(s.substring(start, i));
st.push(new NestedInteger(value));
}
return (NestedInteger)st.pop();
}
}
565. Array Nesting
class Solution {
public int arrayNesting(int[] nums) {
int n = nums.length;
boolean[] visited = new boolean[n];
int res = 0;
for (int i = 0; i < n; i++) {
if(visited[i])
continue;
else{
Stack<Integer> st = new Stack<>();
int cur = i;
while(!visited[cur]){
st.push(cur);
visited[cur] = true;
cur = nums[cur];
}
res = Math.max(res, st.size());
}
}
return res;
}
}
不知道怎么描述的问题
456. 132 Pattern
class Solution {
public boolean find132pattern(int[] nums) {
if(nums == null || nums.length < 3)
return false;
int len = nums.length;
for (int j = 0, min = Integer.MAX_VALUE; j < len; j++) {
min = Math.min(nums[j], min);
if(min == nums[j])
continue;
for (int k = len - 1; k > j; k--) {
if(min < nums[k] && nums[k] < nums[j])
return true;
}
}
return false;
}
}
class Solution {
public boolean find132pattern(int[] nums) {
if(nums == null || nums.length < 3)
return false;
int len = nums.length;
int[] arr = Arrays.copyOf(nums, len);
for (int i = 1; i < len; i++) {
arr[i] = Math.min(nums[i - 1], arr[i - 1]);
}
for (int j = len - 1, top = len; j >= 0; j--) {
if(nums[j] <= arr[j])
continue;
while(top < len && arr[top] <= arr[j])
top++;
if(top < len && nums[j] > arr[top])
return true;
arr[--top] = nums[j];
}
return false;
}
}
880. Decoded String at Index
Approach 1: Work Backwards
class Solution {
public String decodeAtIndex(String S, int K) {
long size = 0;
int n = S.length();
for (int i = 0; i < n; i++) {
char c = S.charAt(i);
if(Character.isDigit(c)){
size *= c - '0';
}else
size++;
}
for (int i = n - 1; i >= 0; i--) {
char c = S.charAt(i);
K %= size;
if(K == 0 && Character.isLetter(c)){
return Character.toString(c);
}
if(Character.isDigit(c)){
size /= c - '0';
}
else
size--;
}
throw null;
}
}
907. Sum of Subarray Minimums
Approach 1: Prev/Next Array
class Solution {
private final static int modulo = (int)Math.pow(10, 9) + 7;
public int sumSubarrayMins(int[] arr) {
int n = arr.length;
Stack<Integer> stack = new Stack<>();
int[] prev = new int[n];
for (int i = 0; i < n; i++) {
while(!stack.isEmpty() && arr[i] <= arr[stack.peek()])
stack.pop();
prev[i] = stack.isEmpty() ? -1 : stack.peek();
stack.push(i);
}
stack = new Stack<>();
int[] next = new int[n];
for (int k = n - 1; k >= 0 ; k--) {
while(!stack.isEmpty() && arr[k] < arr[stack.peek()])
stack.pop();
next[k] = stack.isEmpty() ? n : stack.peek();
stack.push(k);
}
long ans = 0;
for (int i = 0; i < n; i++) {
ans += (i - (long)prev[i]) * ((long)next[i] - i) % modulo * arr[i] % modulo;
ans %= modulo;
}
return (int)ans;
}
}
Next Greater Element
496. Next Greater Element I
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
Map<Integer, Integer> map = new HashMap<>();
Stack<Integer> st = new Stack<>();
for(int num : nums2){
if(st.isEmpty()){
st.push(num);
}else{
while(!st.isEmpty() && st.peek() < num){
map.put(st.pop(), num);
}
st.push(num);
}
}
int[] res = new int[nums1.length];
Arrays.fill(res, -1);
for (int i = 0; i < nums1.length; i++) {
if(map.containsKey(nums1[i])){
res[i] = map.get(nums1[i]);
}
}
return res;
}
}
503. Next Greater Element II
class Solution {
public int[] nextGreaterElements(int[] nums) {
int n = nums.length;
int[] arr = new int[n * 2];
for (int i = 0; i < n; i++) {
arr[i] = nums[i];
arr[n + i] = nums[i];
}
int[] res = new int[n];
Arrays.fill(res, -1);
Stack<int[]> st = new Stack<>();
for (int i = 0; i < 2 * n; i++) {
while(!st.isEmpty() && st.peek()[0] < arr[i]){
res[st.pop()[1]] = arr[i];
}
st.push(new int[]{arr[i], i < n ? i : i - n});
}
return res;
}
}
556. Next Greater Element III
class Solution {
public int nextGreaterElement(int n) {
char[] chars = String.valueOf(n).toCharArray();
int len = chars.length;
int j;
for (j = len - 2; j >= 0 ; j--) {
if(chars[j] < chars[j + 1])
break;
}
if(j < 0)
return -1;
else{
int i;
for (i = len - 1; i > j; i--) {
if(chars[j] < chars[i])
break;
}
char tmp = chars[j];
chars[j] = chars[i];
chars[i] = tmp;
char[] chs = Arrays.copyOfRange(chars, j + 1, len);
Arrays.sort(chs);
for (i = 0; i < chs.length; i++) {
chars[j + 1 + i] = chs[i];
}
long l = Long.parseLong(String.valueOf(chars));
return l > Integer.MAX_VALUE ? -1 : (int)l;
}
}
}
739. Daily Temperatures
class Solution {
public int[] dailyTemperatures(int[] T) {
int n = T.length;
int[] res = new int[n];
Stack<int[]> st = new Stack<>();
for (int i = 0; i < n; i++) {
while(!st.isEmpty() && st.peek()[0] < T[i]){
int[] top = st.pop();
res[top[1]] = i - top[1];
}
st.push(new int[]{T[i], i});
}
return res;
}
}
726. Number of Atoms
Approach 1 : Using Stack
class Solution {
public String countOfAtoms(String formula) {
Stack<Object> st = new Stack<>();
List<Object> objects = parse(formula);
for (Object object : objects) {
if (object instanceof Character && (Character)object == ')'){
List<Object> list = new ArrayList<>();
while(!(st.peek() instanceof Character && (Character)st.peek() == '(')){
list.add(0, st.pop());
}
st.pop();
Map<String, Integer> cal = cal(list);
st.push(cal);
} else if(object instanceof Integer){
if(st.peek() instanceof Map){
Map<String, Integer> map = (Map<String, Integer>) st.pop();
int n = (Integer)object;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
map.put(entry.getKey(), entry.getValue() * n);
}
st.push(map);
}else
st.push(object);
}
else
st.push(object);
}
Map<String, Integer> m = cal(Arrays.asList(st.toArray()));
StringBuilder builder = new StringBuilder();
for (Map.Entry<String, Integer> entry : m.entrySet()) {
builder.append(entry.getKey());
if(entry.getValue() > 1){
builder.append(entry.getValue());
}
}
return builder.toString();
}
private Map<String, Integer> cal(List<Object> list){
Map<String, Integer> res = new TreeMap<>();
int index = 0, len = list.size();
while(index < len){
Object obj = list.get(index);
if(obj instanceof String){
String key = (String)obj;
int count = 1;
if(index + 1 < len && list.get(index + 1) instanceof Integer){
count = (int) list.get(index + 1);
index++;
}
res.put(key, res.getOrDefault(key, 0) + count);
}else if(obj instanceof Map){
Map<String, Integer> map = (Map<String, Integer>) obj;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
res.put(entry.getKey(), res.getOrDefault(entry.getKey(), 0) + entry.getValue());
}
}else;
index++;
}
return res;
}
private List<Object> parse(String formula){
List<Object> res = new LinkedList<>();
int s = -1, len = formula.length();
int flag = -1; // -1 invalid, 0 element, 1 count
for (int i = 0; i < len; i++) {
char ch = formula.charAt(i);
if(Character.isDigit(ch)){
if(flag == -1){
flag = 1;
s = i;
}else if(flag == 0){
res.add(formula.substring(s, i));
flag = 1;
s = i;
}else
;
}else if(Character.isUpperCase(ch)){
if(flag == -1){
flag = 0;
s = i;
}else if(flag == 1){
res.add(Integer.parseInt(formula.substring(s, i)));
flag = 0;
s = i;
}else {
res.add(formula.substring(s, i));
flag = 0;
s = i;
}
}else if(ch == '(' || ch == ')'){
if(flag == -1){
res.add(ch);
s = -1;
}else if(flag == 0){
res.add(formula.substring(s, i));
flag = -1;
s = -1;
res.add(ch);
}else if(flag == 1){
res.add(Integer.parseInt(formula.substring(s, i)));
flag = -1;
s = -1;
res.add(ch);
}else
;
}else
;
}
if(flag == 0) {
res.add(formula.substring(s));
}else if(flag == 1){
res.add(Integer.parseInt(formula.substring(s)));
}
return res;
}
}
Remove elements
402. Remove K Digits
Approach 1
class Solution {
public String removeKdigits(String num, int k) {
if(k == 0){
while(num.length() > 0 && num.charAt(0) == '0')
num = num.substring(1);
return num.length() == 0 ? "0" : num;
}
int j = 0;
for (; j + 1 < num.length(); j++) {
if(num.charAt(j) > num.charAt(j + 1))
break;
}
String s;
if(j == 0)
s = num.substring(1);
else if (j == num.length() - 1)
s = num.substring(0, num.length() - 1);
else
s = num.substring(0, j) + num.substring(j + 1);
return removeKdigits(s, k - 1);
}
}
Approach 2 : Using Stack
class Solution {
public String removeKdigits(String num, int k) {
int len = num.length();
if(k == len)
return "0";
Stack<Character> stack = new Stack<>();
int i = 0;
while(i < len){
while(k > 0 && !stack.isEmpty() && stack.peek() > num.charAt(i)){
stack.pop();
k--;
}
stack.push(num.charAt(i));
i++;
}
//covering case like "1111"
while(k > 0){
stack.pop();
k--;
}
StringBuilder builder = new StringBuilder();
for (Character character : stack) {
builder.append(character);
}
while(builder.length() > 1 && builder.charAt(0) == '0')
builder.deleteCharAt(0);
return builder.toString();
}
}
1081. Smallest Subsequence of Distinct Characters
class Solution {
public String smallestSubsequence(String s) {
int[] lastIdxes = new int[26];
boolean[] visited = new boolean[26];
char[] chs = s.toCharArray();
for (int i = 0; i < chs.length; i++) {
lastIdxes[chs[i] - 'a'] = i;
}
Stack<Character> stack = new Stack<>();
int index = 0;
for (int i = 0; i < chs.length; i++) {
char ch = chs[i];
index = ch - 'a';
if(visited[index])
continue;
while(!stack.isEmpty() && ch < stack.peek() && lastIdxes[stack.peek() - 'a'] > i)
visited[stack.pop() - 'a'] = false;
stack.push(ch);
visited[index] = true;
}
StringBuilder builder = new StringBuilder();
for (Character character : stack) {
builder.append(character);
}
return builder.toString();
}
}
1673. Find the Most Competitive Subsequence
class Solution {
public int[] mostCompetitive(int[] nums, int k) {
Stack<Integer> stack = new Stack<>();
int[] result = new int[k];
for (int i = 0; i < nums.length; i++) {
while(!stack.empty() && nums[i] < nums[stack.peek()] && nums.length - i + stack.size() > k){
stack.pop();
}
if(stack.size() < k){
stack.push(i);
}
}
for (int i = k - 1; i >= 0; i--) {
result[i] = nums[stack.pop()];
}
return result;
}
}