diff --git a/Concurrency/Building H2O.java b/Concurrency/Building H2O.java new file mode 100644 index 00000000..04fda0bc --- /dev/null +++ b/Concurrency/Building H2O.java @@ -0,0 +1,24 @@ +class H2O { + + private Semaphore hydrogenSemaphore; + private Semaphore oxygenSemaphore; + + public H2O() { + this.hydrogenSemaphore = new Semaphore(2); + this.oxygenSemaphore = new Semaphore(0); + } + + public void hydrogen(Runnable releaseHydrogen) throws InterruptedException { + hydrogenSemaphore.acquire(); + // releaseHydrogen.run() outputs "H". Do not change or remove this line. + releaseHydrogen.run(); + this.oxygenSemaphore.release(); + } + + public void oxygen(Runnable releaseOxygen) throws InterruptedException { + this.oxygenSemaphore.acquire(2); + // releaseOxygen.run() outputs "O". Do not change or remove this line. + releaseOxygen.run(); + this.hydrogenSemaphore.release(2); + } +} diff --git a/Concurrency/Design Bounded Blocking Queue.java b/Concurrency/Design Bounded Blocking Queue.java new file mode 100644 index 00000000..a8e0a3d2 --- /dev/null +++ b/Concurrency/Design Bounded Blocking Queue.java @@ -0,0 +1,42 @@ +class BoundedBlockingQueue { + + private final Queue queue; + private final Semaphore mutex; + private final Semaphore items; + private final Semaphore capacityTracker; + private int currentCapacity; + + public BoundedBlockingQueue(int capacity) { + this.queue = new LinkedList<>(); + this.mutex = new Semaphore(1); + this.items = new Semaphore(0); + this.capacityTracker = new Semaphore(capacity); + this.currentCapacity = 0; + } + + public void enqueue(int element) throws InterruptedException { + this.capacityTracker.acquire(); + this.mutex.acquire(); + this.queue.add(element); + this.currentCapacity++; + this.mutex.release(); + this.items.release(); + } + + public int dequeue() throws InterruptedException { + this.items.acquire(); + this.mutex.acquire(); + int result = this.queue.remove(); + this.currentCapacity--; + this.mutex.release(); + this.capacityTracker.release(); + return result; + } + + public int size() throws InterruptedException { + this.mutex.acquire(); + int currentSize = this.currentCapacity; + this.mutex.release(); + return currentSize; + } +} diff --git a/Concurrency/Fizz Buzz Multithreaded.java b/Concurrency/Fizz Buzz Multithreaded.java new file mode 100644 index 00000000..b749ba25 --- /dev/null +++ b/Concurrency/Fizz Buzz Multithreaded.java @@ -0,0 +1,71 @@ +class FizzBuzz { + private int n; + private final Semaphore fizzSemaphore; + private final Semaphore buzzSemaphore; + private final Semaphore fizzBuzzSemaphore; + private final Semaphore numSemaphore; + + public FizzBuzz(int n) { + this.n = n; + this.fizzSemaphore = new Semaphore(0); + this.buzzSemaphore = new Semaphore(0); + this.fizzBuzzSemaphore = new Semaphore(0); + this.numSemaphore = new Semaphore(1); + } + + // printFizz.run() outputs "fizz". + public void fizz(Runnable printFizz) throws InterruptedException { + for (int i = 1; i <= n; i++) { + if (i % 3 == 0 && i % 5 != 0) { + fizzSemaphore.acquire(); + printFizz.run(); + releaseLock(i + 1); + } + } + } + + // printBuzz.run() outputs "buzz". + public void buzz(Runnable printBuzz) throws InterruptedException { + for (int i = 1; i <= n; i++) { + if (i % 3 != 0 && i % 5 == 0) { + buzzSemaphore.acquire(); + printBuzz.run(); + releaseLock(i + 1); + } + } + } + + // printFizzBuzz.run() outputs "fizzbuzz". + public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException { + for (int i = 1; i <= n; i++) { + if (i % 3 == 0 && i % 5 == 0) { + fizzBuzzSemaphore.acquire(); + printFizzBuzz.run(); + releaseLock(i + 1); + } + } + } + + // printNumber.accept(x) outputs "x", where x is an integer. + public void number(IntConsumer printNumber) throws InterruptedException { + for (int i = 1; i <= n; i++) { + if (i % 3 != 0 && i % 5 != 0) { + numSemaphore.acquire(); + printNumber.accept(i); + releaseLock(i + 1); + } + } + } + + private void releaseLock(int num) { + if (num % 3 == 0 && num % 5 == 0) { + fizzBuzzSemaphore.release(); + } else if (num % 3 == 0 && num % 5 != 0) { + fizzSemaphore.release(); + } else if (num % 3 != 0 && num % 5 == 0) { + buzzSemaphore.release(); + } else { + numSemaphore.release(); + } + } +} diff --git a/Concurrency/Print FooBar Alternately.java b/Concurrency/Print FooBar Alternately.java new file mode 100644 index 00000000..94fa19cc --- /dev/null +++ b/Concurrency/Print FooBar Alternately.java @@ -0,0 +1,33 @@ +class FooBar { + private int n; + + private final Semaphore fooMutex; + private final Semaphore barMutex; + + public FooBar(int n) { + this.n = n; + this.fooMutex = new Semaphore(1); + this.barMutex = new Semaphore(0); + } + + public void foo(Runnable printFoo) throws InterruptedException { + + for (int i = 0; i < n; i++) { + + // printFoo.run() outputs "foo". Do not change or remove this line. + this.fooMutex.acquire(); + printFoo.run(); + this.barMutex.release(); + } + } + + public void bar(Runnable printBar) throws InterruptedException { + + for (int i = 0; i < n; i++) { + this.barMutex.acquire(); + // printBar.run() outputs "bar". Do not change or remove this line. + printBar.run(); + this.fooMutex.release(); + } + } +} diff --git a/Concurrency/Print Zero Even Odd.java b/Concurrency/Print Zero Even Odd.java new file mode 100644 index 00000000..784b7fd7 --- /dev/null +++ b/Concurrency/Print Zero Even Odd.java @@ -0,0 +1,43 @@ +class ZeroEvenOdd { + private int n; + + private final Semaphore zeroMutex; + private final Semaphore oddMutex; + private final Semaphore evenMutex; + + public ZeroEvenOdd(int n) { + this.n = n; + this.zeroMutex = new Semaphore(1); + this.oddMutex = new Semaphore(0); + this.evenMutex = new Semaphore(0); + } + + // printNumber.accept(x) outputs "x", where x is an integer. + public void zero(IntConsumer printNumber) throws InterruptedException { + for (int i = 0; i < n; i++) { + this.zeroMutex.acquire(); + printNumber.accept(0); + if (i % 2 == 0) { + this.oddMutex.release(); + } else { + this.evenMutex.release(); + } + } + } + + public void even(IntConsumer printNumber) throws InterruptedException { + for (int i = 2; i <= n; i += 2) { + this.evenMutex.acquire(); + printNumber.accept(i); + this.zeroMutex.release(); + } + } + + public void odd(IntConsumer printNumber) throws InterruptedException { + for (int i = 1; i <= n; i += 2) { + this.oddMutex.acquire(); + printNumber.accept(i); + this.zeroMutex.release(); + } + } +} diff --git a/Concurrency/Print in Order.java b/Concurrency/Print in Order.java index a23042a0..f9de39ff 100644 --- a/Concurrency/Print in Order.java +++ b/Concurrency/Print in Order.java @@ -1,53 +1,44 @@ +import java.util.concurrent.atomic.AtomicInteger; + class Foo { - - private int counter = 1; - private String mutex = ""; - public Foo() { - - } - public void first(Runnable printFirst) throws InterruptedException { - - // printFirst.run() outputs "first". Do not change or remove this line. - boolean flag = true; - while (flag) { - synchronized(mutex) { - if (counter == 1) { - printFirst.run(); - counter++; - flag = false; - } - } - } + private Object lock; + private AtomicInteger counter; + + public Foo() { + this.lock = new Object(); + this.counter = new AtomicInteger(0); + } + + public void first(Runnable printFirst) throws InterruptedException { + + // printFirst.run() outputs "first". Do not change or remove this line. + synchronized (lock) { + printFirst.run(); + this.counter.incrementAndGet(); + this.lock.notifyAll(); } + } - public void second(Runnable printSecond) throws InterruptedException { - - // printSecond.run() outputs "second". Do not change or remove this line. - boolean flag = true; - while (flag) { - synchronized(mutex) { - if (counter == 2) { - printSecond.run(); - counter++; - flag = false; - } - } - } + public void second(Runnable printSecond) throws InterruptedException { + // printSecond.run() outputs "second". Do not change or remove this line. + synchronized (lock) { + while (this.counter.get() != 1) { + this.lock.wait(); + } + printSecond.run(); + this.counter.incrementAndGet(); + this.lock.notifyAll(); } + } - public void third(Runnable printThird) throws InterruptedException { - - // printThird.run() outputs "third". Do not change or remove this line. - boolean flag = true; - while (flag) { - synchronized(mutex) { - if (counter == 3) { - printThird.run(); - counter++; - flag = false; - } - } - } + public void third(Runnable printThird) throws InterruptedException { + // printThird.run() outputs "third". Do not change or remove this line. + synchronized (lock) { + while (this.counter.get() != 2) { + this.lock.wait(); + } + printThird.run(); } + } } diff --git a/Concurrency/README.md b/Concurrency/README.md new file mode 100644 index 00000000..8bc6ef63 --- /dev/null +++ b/Concurrency/README.md @@ -0,0 +1,11 @@ +# Concurrency LeetCode Java Solutions +S.no | Coding Problem +--- | --- +1 | [Building H2O](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Concurrency/Building%20H2O.java) +2 | [Design Bounded Blocking Queue](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Concurrency/Design%20Bounded%20Blocking%20Queue.java) +3 | [Fizz Buzz Multithreaded](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Concurrency/Fizz%20Buzz%20Multithreaded.java) +4 | [Print FooBar Alternately](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Concurrency/Print%20FooBar%20Alternately.java) +5 | [Print Zero Even Odd](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Concurrency/Print%20Zero%20Even%20Odd.java) +6 | [Print in Order](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Concurrency/Print%20in%20Order.java) +7 | [The Dining Philosophers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Concurrency/The%20Dining%20Philosophers.java) +8 | [Traffic Light Controlled Intersection](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Concurrency/Traffic%20Light%20Controlled%20Intersection.java) diff --git a/Concurrency/The Dining Philosophers.java b/Concurrency/The Dining Philosophers.java new file mode 100644 index 00000000..01409d64 --- /dev/null +++ b/Concurrency/The Dining Philosophers.java @@ -0,0 +1,51 @@ +class DiningPhilosophers { + + private List forks; + private Semaphore dinersOnTable; + private List state; + + public DiningPhilosophers() { + this.forks = new ArrayList<>(); + this.state = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + this.forks.add(new Semaphore(1)); + this.state.add("idle"); + } + this.dinersOnTable = new Semaphore(4); + } + + // call the run() method of any runnable to execute its code + public void wantsToEat(int philosopher, + Runnable pickLeftFork, + Runnable pickRightFork, + Runnable eat, + Runnable putLeftFork, + Runnable putRightFork) throws InterruptedException { + int leftForkIdx = philosopher; + int rightForkIdx = (philosopher + 4) % 5; + + this.dinersOnTable.acquire(); + if (this.state.get(philosopher).equals("eating")) { + this.dinersOnTable.release(); + return; + } + this.state.set(philosopher, "eating"); + pickFork(leftForkIdx, pickLeftFork); + pickFork(rightForkIdx, pickRightFork); + eat.run(); + putFork(rightForkIdx, putRightFork); + putFork(leftForkIdx, putLeftFork); + this.state.set(philosopher, "idle"); + this.dinersOnTable.release(); + } + + private void putFork(int idx, Runnable put) { + put.run(); + this.forks.get(idx).release(); + } + + private void pickFork(int idx, Runnable pick) throws InterruptedException { + this.forks.get(idx).acquire(); + pick.run(); + } +} diff --git a/Concurrency/Traffic Light Controlled Intersection.java b/Concurrency/Traffic Light Controlled Intersection.java new file mode 100644 index 00000000..3328a2e8 --- /dev/null +++ b/Concurrency/Traffic Light Controlled Intersection.java @@ -0,0 +1,26 @@ +class TrafficLight { + + private boolean greenOnRoadA; + private ReentrantLock lock; + + public TrafficLight() { + this.greenOnRoadA = true; + this.lock = new ReentrantLock(); + } + + public void carArrived( + int carId, // ID of the car + int roadId, // ID of the road the car travels on. Can be 1 (road A) or 2 (road B) + int direction, // Direction of the car + Runnable turnGreen, // Use turnGreen.run() to turn light to green on current road + Runnable crossCar // Use crossCar.run() to make car cross the intersection + ) { + this.lock.lock(); + if(greenOnRoadA && roadId==2 || !greenOnRoadA && roadId==1){ + greenOnRoadA = !greenOnRoadA; + turnGreen.run(); + } + crossCar.run(); + this.lock.unlock(); + } +} diff --git a/Concurrency/Web Crawler Multithreaded.java b/Concurrency/Web Crawler Multithreaded.java new file mode 100644 index 00000000..bb48616c --- /dev/null +++ b/Concurrency/Web Crawler Multithreaded.java @@ -0,0 +1,108 @@ +/** + * // This is the HtmlParser's API interface. + * // You should not implement it, or speculate about its implementation + * interface HtmlParser { + * public List getUrls(String url) {} + * } + */ +import java.net.URI; +import java.net.URISyntaxException; + + +class Solution { + public List crawl(String startUrl, HtmlParser htmlParser) { + ResultRecord resultRecord = new ResultRecord(); + CrawlTask task = new CrawlTask( + startUrl, htmlParser, resultRecord, UrlUtil.parseHostname(startUrl)); + try { + task.start(); + task.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return resultRecord.getResultList(); + } +} + +class CrawlTask extends Thread { + + private final String url; + private final HtmlParser htmlParser; + private final ResultRecord resultRecord; + private final String parentHost; + + public CrawlTask(String url, + HtmlParser htmlParser, + ResultRecord resultRecord, + String parentHost) { + this.url = url; + this.htmlParser = htmlParser; + this.resultRecord = resultRecord; + this.parentHost = parentHost; + } + + public void run() { + String hostname = UrlUtil.parseHostname(url); + if (!hostname.equals(parentHost)) { + return; + } + if (resultRecord.addIfNotExists(url)) { + List childUrls = htmlParser.getUrls(url); + List tasks = new ArrayList<>(); + for (String childUrl : childUrls) { + tasks.add(new CrawlTask( + childUrl, htmlParser, resultRecord, parentHost)); + } + try { + for (CrawlTask task : tasks) { + task.start(); + } + for (CrawlTask task : tasks) { + task.join(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} + +class UrlUtil { + + public static String parseHostname(String url) { + try { + URI uri = new URI(url); + return uri.getHost(); + } catch(URISyntaxException e) { + e.printStackTrace(); + } + return null; + } +} + +class ResultRecord { + + private Set urls; + private Semaphore mutex; + + public ResultRecord() { + this.urls = new HashSet<>(); + this.mutex = new Semaphore(1); + } + + public boolean addIfNotExists(String url) { + try { + this.mutex.acquire(); + boolean added = this.urls.add(url); + this.mutex.release(); + return added; + } catch (InterruptedException e) { + e.printStackTrace(); + } + return false; + } + + public List getResultList() { + return new ArrayList<>(urls); + } +} diff --git a/Contests/Weekly Contest 102/Fruits Into Basket.java b/Contests/Weekly Contest 102/Fruits Into Basket.java deleted file mode 100644 index 6d509ca1..00000000 --- a/Contests/Weekly Contest 102/Fruits Into Basket.java +++ /dev/null @@ -1,34 +0,0 @@ -class Solution { - public static int totalFruit(int[] tree) { - int maxFruits = Integer.MIN_VALUE; - int count = 0; - Map map = new HashMap<>(); - int start = 0; - - for (int num : tree) { - if (map.size() < 2 || map.containsKey(num)) { - map.put(num, map.getOrDefault(num, 0) + 1); - count++; - } - else { - map.put(num, map.getOrDefault(num, 0) + 1); - count++; - - while (true) { - int key = tree[start++]; - map.put(key, map.get(key)-1); - count--; - - if (map.get(key) == 0) { - map.remove(key); - break; - } - } - } - - maxFruits = Math.max(maxFruits, count); - } - - return Math.max(count, maxFruits); - } -} diff --git a/Contests/Weekly Contest 102/Sort Array By Parity.java b/Contests/Weekly Contest 102/Sort Array By Parity.java deleted file mode 100644 index 96bf6ca0..00000000 --- a/Contests/Weekly Contest 102/Sort Array By Parity.java +++ /dev/null @@ -1,28 +0,0 @@ -class Solution { - public static int[] sortArrayByParity(int[] A) { - List even = new ArrayList<>(); - List odd = new ArrayList<>(); - - - for (int num : A) { - if (num%2 == 0) { - even.add(num); - } - else { - odd.add(num); - } - } - - int i = 0; - - for (int num : even) { - A[i++] = num; - } - - for (int num : odd) { - A[i++] = num; - } - - return A; - } -} diff --git a/Contests/Weekly Contest 102/Sum of Subarray Minimums.java b/Contests/Weekly Contest 102/Sum of Subarray Minimums.java deleted file mode 100644 index 5126978f..00000000 --- a/Contests/Weekly Contest 102/Sum of Subarray Minimums.java +++ /dev/null @@ -1,32 +0,0 @@ -class Solution { - public static int sumSubarrayMins(int[] A) { - Stack> stack = new Stack<>(); - int n = A.length; - int tempSum = 0; - int mod = 1000000007; - int ans = 0; - - for (int i = 0; i < n; i++) { - if((!stack.empty()) && A[i] >= stack.peek().get(0)) { - tempSum += A[i]; - stack.push(Arrays.asList(A[i], 1)); - } - else { - int count = 1; - - while((!stack.empty()) && stack.peek().get(0) > A[i]) { - count += stack.peek().get(1); - tempSum -= stack.peek().get(1) * stack.peek().get(0); - stack.pop(); - } - - stack.push(Arrays.asList(A[i], count)); - tempSum += count * A[i]; - } - - ans = (ans + tempSum)%mod; - } - - return ans; - } -} diff --git a/Contests/Weekly Contest 103/Online Election.java b/Contests/Weekly Contest 103/Online Election.java deleted file mode 100644 index 86ed54fa..00000000 --- a/Contests/Weekly Contest 103/Online Election.java +++ /dev/null @@ -1,46 +0,0 @@ -class TopVotedCandidate { - int[] times; - int[] persons; - int[] winner; - - public TopVotedCandidate(int[] persons, int[] times) { - this.times = times; - this.persons = persons; - int[] counter = new int[persons.length+1]; - winner = new int[times.length]; - int max = Integer.MIN_VALUE; - int maxPerson = -1; - int i = 0; - - while (i < times.length) { - counter[persons[i]]++; - if (max < counter[persons[i]]) { - max = counter[persons[i]]; - maxPerson = persons[i]; - } - else if (max == counter[persons[i]]) { - maxPerson = persons[i]; - } - - winner[i] = maxPerson; - - i++; - } - } - - public int q(int t) { - int i = 0; - while (i < times.length && times[i] <= t) { - i++; - } - - return winner[i-1]; - } -} - - -/** - * Your TopVotedCandidate object will be instantiated and called as such: - * TopVotedCandidate obj = new TopVotedCandidate(persons, times); - * int param_1 = obj.q(t); - */ diff --git a/Contests/Weekly Contest 103/Smallest Range I.java b/Contests/Weekly Contest 103/Smallest Range I.java deleted file mode 100644 index b93686ed..00000000 --- a/Contests/Weekly Contest 103/Smallest Range I.java +++ /dev/null @@ -1,7 +0,0 @@ -class Solution { - - public static int smallestRangeI(int[] A, int K) { - Arrays.sort(A); - return Math.max((A[A.length-1] - K) - (A[0] + K), 0); - } -} diff --git a/Contests/Weekly Contest 103/Smallest Range II.java b/Contests/Weekly Contest 103/Smallest Range II.java deleted file mode 100644 index 2ad7c801..00000000 --- a/Contests/Weekly Contest 103/Smallest Range II.java +++ /dev/null @@ -1,16 +0,0 @@ -class Solution { - public int smallestRangeII(int[] A, int K) { - int N = A.length; - Arrays.sort(A); - int ans = A[N-1] - A[0]; - - for (int i=0; i=0; i--) { - minVal = Math.min(minVal, A[i]); - min[i] = minVal; - } - - int[] max = new int[A.length]; - int maxVal = Integer.MIN_VALUE; - - for (int i=0; i wordSubsets(String[] A, String[] B) { - Map> map1 = getMap(A); - - Map map2 = new HashMap<>(); - for (String s : B) { - Map temp = new HashMap<>(); - char[] tempChar = s.toCharArray(); - - for (char c : tempChar) { - temp.put(c, temp.getOrDefault(c, 0) + 1); - } - - for (Map.Entry entry : temp.entrySet()) { - int val1 = entry.getValue(); - int val2 = map2.getOrDefault(entry.getKey(), 0); - - map2.put(entry.getKey(), Math.max(val1, val2)); - } - } - - List ans = new ArrayList<>(); - - for (String s : A) { - boolean flag = true; - Map temp2 = map1.get(s); - - for (Map.Entry entry : map2.entrySet()) { - if (!(temp2.containsKey(entry.getKey()) && temp2.get(entry.getKey()) >= entry.getValue())) { - flag = false; - break; - } - } - - if (flag) { - ans.add(s); - } - } - - return ans; - } - - private static Map> getMap(String[] A) { - Map> map = new HashMap<>(); - - for (String a : A) { - char[] arr = a.toCharArray(); - Map charMap = new HashMap<>(); - for (char c : arr) { - charMap.put(c, charMap.getOrDefault(c, 0) + 1); - } - - map.put(a, charMap); - } - - return map; - } -} diff --git a/Contests/Weekly Contest 104/X of a Kind in a Deck of Cards.java b/Contests/Weekly Contest 104/X of a Kind in a Deck of Cards.java deleted file mode 100644 index 327fc563..00000000 --- a/Contests/Weekly Contest 104/X of a Kind in a Deck of Cards.java +++ /dev/null @@ -1,47 +0,0 @@ -class Solution { - public static boolean hasGroupsSizeX(int[] deck) { - Map map = new HashMap<>(); - - for (int card: deck) { - map.put(card, map.getOrDefault(card, 0) + 1); - } - - int X = -1; - - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() < 2) { - return false; - } - - if (X == -1) { - X = entry.getValue(); - } - else { - X = findGCD(X, entry.getValue()); - } - } - - if (X == 1) { - return false; - } - - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() % X != 0) { - return false; - } - } - - return true; - } - - private static int findGCD(int n1, int n2) { - while(n1 != n2) { - if(n1 > n2) - n1 -= n2; - else - n2 -= n1; - } - - return n1; - } -} diff --git a/Contests/Weekly Contest 105/Maximum Sum Circular Subarray.java b/Contests/Weekly Contest 105/Maximum Sum Circular Subarray.java deleted file mode 100644 index bdc17368..00000000 --- a/Contests/Weekly Contest 105/Maximum Sum Circular Subarray.java +++ /dev/null @@ -1,28 +0,0 @@ -class Solution { - public static int maxSubarraySumCircular(int[] A) { - int max = kadane(A); - int wrap = 0; - - for(int i=0; i < A.length; i++) { - wrap = wrap+A[i]; - A[i] *= -1; - } - - wrap = wrap + kadane(A); - - return Math.abs(wrap) < Math.abs(max) ? max : wrap; - } - - - private static int kadane(int[] a){ - int maxSoFar=a[0]; - int maxGlobal =a[0]; - - for(int i=1; i map = new HashMap<>(); - for (int i=start; i open = new Stack<>(); - int count = 0; - - for (char c : S.toCharArray()) { - if (c == '(') { - open.push(c); - } - else { - if (open.empty()) { - count++; - } - else { - open.pop(); - } - } - } - - count += open.size(); - - return count; - } -} diff --git a/Contests/Weekly Contest 106/Sort Array By Parity II.java b/Contests/Weekly Contest 106/Sort Array By Parity II.java deleted file mode 100644 index 1289a2e4..00000000 --- a/Contests/Weekly Contest 106/Sort Array By Parity II.java +++ /dev/null @@ -1,35 +0,0 @@ -class Solution { - public int[] sortArrayByParityII(int[] A) { - int[] ans = new int[A.length]; - int[] odd = new int[A.length/2]; - int[] even = new int[A.length/2]; - - int i = 0; - int j = 0; - int k = 0; - - while (k < A.length) { - if (A[k]%2 == 0) { - even[j++] = A[k++]; - } - else { - odd[i++] = A[k++]; - } - } - - i = 0; - j = 0; - k = 0; - - while (k < ans.length) { - if (k%2 == 0) { - ans[k++] = even[j++]; - } - else { - ans[k++] = odd[i++]; - } - } - - return ans; - } -} diff --git a/Contests/Weekly Contest 107/Flip String to Monotone Increasing.java b/Contests/Weekly Contest 107/Flip String to Monotone Increasing.java deleted file mode 100644 index 6f98ab13..00000000 --- a/Contests/Weekly Contest 107/Flip String to Monotone Increasing.java +++ /dev/null @@ -1,27 +0,0 @@ -class Solution { - public static int minFlipsMonoIncr(String S) { - int zeroCount = 0; - int flipCount = 0; - int oneCount = 0; - - for (char c : S.toCharArray()) { - if (c == '0') { - if (oneCount == 0) { - continue; - } - else { - flipCount++; - } - } - else { - oneCount++; - } - - if (flipCount > oneCount) { - flipCount = oneCount; - } - } - - return flipCount; - } -} diff --git a/Contests/Weekly Contest 107/Long Pressed Name.java b/Contests/Weekly Contest 107/Long Pressed Name.java deleted file mode 100644 index 5bf9065a..00000000 --- a/Contests/Weekly Contest 107/Long Pressed Name.java +++ /dev/null @@ -1,29 +0,0 @@ -class Solution { - public static boolean isLongPressedName(String name, String typed) { - int slow = 0; - int fast = 0; - - while (slow < name.length() && fast < typed.length()) { - if (name.charAt(slow) == typed.charAt(fast)) { - slow++; - fast++; - } - else if (fast > 0 && typed.charAt(fast) == typed.charAt(fast-1)) { - fast++; - } - else { - return false; - } - } - - while (fast < typed.length()) { - if (typed.charAt(fast) != typed.charAt(fast-1)) { - return false; - } - - fast++; - } - - return slow == name.length(); - } -} diff --git a/Contests/Weekly Contest 108/Binary Subarrays With Sum.java b/Contests/Weekly Contest 108/Binary Subarrays With Sum.java deleted file mode 100644 index 37cc0a30..00000000 --- a/Contests/Weekly Contest 108/Binary Subarrays With Sum.java +++ /dev/null @@ -1,18 +0,0 @@ -class Solution { - public int numSubarraysWithSum(int[] A, int S) { - Map c = new HashMap<>(); - - c.put(0, 1); - - int psum = 0; - int res = 0; - - for (int i : A) { - psum += i; - res += c.getOrDefault(psum - S, 0); - c.put(psum, c.getOrDefault(psum, 0)+1); - } - - return res; - } -} diff --git a/Contests/Weekly Contest 108/Minimum Falling Path Sum.java b/Contests/Weekly Contest 108/Minimum Falling Path Sum.java deleted file mode 100644 index 056d9501..00000000 --- a/Contests/Weekly Contest 108/Minimum Falling Path Sum.java +++ /dev/null @@ -1,37 +0,0 @@ -class Solution { - public int minFallingPathSum(int[][] A) { - int n = A.length; - int[][] dp = new int[n][n]; - - for (int[] arr : dp) { - Arrays.fill(arr, Integer.MAX_VALUE); - } - - for (int i=0; i= 0) { - dp[i][j] = Math.min(dp[i][j], dp[i-1][j-1]); - } - - if (j+1 < A.length) { - dp[i][j] = Math.min(dp[i][j], dp[i-1][j+1]); - } - - dp[i][j] += A[i][j]; - } - } - } - - int minVal = Integer.MAX_VALUE; - for (int num : dp[n-1]) { - minVal = Math.min(minVal, num); - } - - return minVal; - } -} diff --git a/Contests/Weekly Contest 108/Unique Email Addresses.java b/Contests/Weekly Contest 108/Unique Email Addresses.java deleted file mode 100644 index b234df03..00000000 --- a/Contests/Weekly Contest 108/Unique Email Addresses.java +++ /dev/null @@ -1,20 +0,0 @@ -class Solution { - public int numUniqueEmails(String[] emails) { - Set set = new HashSet<>(); - - for (String email : emails) { - String localName = email.split("@")[0]; - String domainName = email.split("@")[1]; - - localName = localName.replace(".", ""); - int idx = localName.indexOf('+'); - if (idx != -1) { - localName = localName.substring(0, idx); - } - - set.add(localName+"@"+domainName); - } - - return set.size(); - } -} diff --git a/Contests/Weekly Contest 109/Knight Dialer.java b/Contests/Weekly Contest 109/Knight Dialer.java deleted file mode 100644 index 3626b968..00000000 --- a/Contests/Weekly Contest 109/Knight Dialer.java +++ /dev/null @@ -1,25 +0,0 @@ -class Solution { - public int knightDialer(int N) { - int MOD = 1000000007; - long[] counts = new long[10]; - Arrays.fill(counts, 1); - long[] temp; - - for (int i=1; i<=N-1; i++) { - temp = counts.clone(); - - counts[0] = (temp[4] + temp[6]) % MOD; - counts[1] = (temp[6] + temp[8]) % MOD; - counts[2] = (temp[7] + temp[9]) % MOD; - counts[3] = (temp[4] + temp[8]) % MOD; - counts[4] = (temp[3] + temp[9] + temp[0]) % MOD; - counts[5] = 0; - counts[6] = (temp[1] + temp[7] + temp[0]) % MOD; - counts[7] = (temp[2] + temp[6]) % MOD; - counts[8] = (temp[1] + temp[3]) % MOD; - counts[9] = (temp[2] + temp[4]) % MOD; - } - - return (int)(Arrays.stream(counts).sum()%MOD); - } -} diff --git a/Contests/Weekly Contest 109/Number of Recent Calls.java b/Contests/Weekly Contest 109/Number of Recent Calls.java deleted file mode 100644 index 097b56c8..00000000 --- a/Contests/Weekly Contest 109/Number of Recent Calls.java +++ /dev/null @@ -1,23 +0,0 @@ -class RecentCounter { - - Queue queue; - public RecentCounter() { - queue = new LinkedList<>(); - } - - public int ping(int t) { - while (!queue.isEmpty() && t - queue.peek() > 3000) { - queue.remove(); - } - - queue.add(t); - - return queue.size(); - } -} - -/** - * Your RecentCounter object will be instantiated and called as such: - * RecentCounter obj = new RecentCounter(); - * int param_1 = obj.ping(t); - */ diff --git a/Contests/Weekly Contest 110/Distinct Subsequence II.java b/Contests/Weekly Contest 110/Distinct Subsequence II.java deleted file mode 100644 index af605fb7..00000000 --- a/Contests/Weekly Contest 110/Distinct Subsequence II.java +++ /dev/null @@ -1,12 +0,0 @@ -class Solution { - public int distinctSubseqII(String s) { - long[] occurenceIndx = new long[26]; - long MOD = 1000000007; - - for (char c : s.toCharArray()) { - occurenceIndx[c - 'a'] = Arrays.stream(occurenceIndx).sum() % MOD + 1; - } - - return (int) (Arrays.stream(occurenceIndx).sum() % MOD); - } -} diff --git a/Contests/Weekly Contest 110/Minimum Area Rectangle.java b/Contests/Weekly Contest 110/Minimum Area Rectangle.java deleted file mode 100644 index be63eb90..00000000 --- a/Contests/Weekly Contest 110/Minimum Area Rectangle.java +++ /dev/null @@ -1,32 +0,0 @@ -class Solution { - public int minAreaRect(int[][] points) { - Map> rows = new TreeMap<>(); - for (int[] point : points) { - int x = point[0]; - int y = point[1]; - rows.computeIfAbsent(x , z -> new ArrayList<>()).add(y); - } - - int ans = Integer.MAX_VALUE; - Map lastIdx = new HashMap<>(); - for (int key : rows.keySet()) { - List row = rows.get(key); - Collections.sort(row); - - for (int i=0; i= low && root.val <= high) { - sum += root.val; - rangeSumBSTHelper(root.right, low, high); - rangeSumBSTHelper(root.left, low, high); - } - else { - if (root.val < low) { - rangeSumBSTHelper(root.right, low, high); - } - - if (root.val > high) { - rangeSumBSTHelper(root.left, low, high); - } - } - } -} diff --git a/Contests/Weekly Contest 110/Reorder Log Files.java b/Contests/Weekly Contest 110/Reorder Log Files.java deleted file mode 100644 index 6e2d505c..00000000 --- a/Contests/Weekly Contest 110/Reorder Log Files.java +++ /dev/null @@ -1,53 +0,0 @@ -class Solution { - public String[] reorderLogFiles(String[] logs) { - List letterLogs = new ArrayList<>(); - List digitLogs = new ArrayList<>(); - - for (String log : logs) { - if(Character.isDigit(log.split("\\s+")[1].charAt(0))) { - digitLogs.add(log); - } - else { - letterLogs.add(log); - } - } - - Collections.sort(letterLogs, new Comparator() { - @Override - public int compare(String o1, String o2) { - String[] s1 = o1.split("\\s+"); - String[] s2 = o2.split("\\s+"); - - StringBuilder sb1 = new StringBuilder(); - StringBuilder sb2 = new StringBuilder(); - - for (int i=1; i 0 && A[j] < A[j-1]) { - j--; - } - - return i > 0 && i == j && j < n; - } -} diff --git a/Contests/Weekly Contest 112/Bag of Tokens.java b/Contests/Weekly Contest 112/Bag of Tokens.java deleted file mode 100644 index 610c54e4..00000000 --- a/Contests/Weekly Contest 112/Bag of Tokens.java +++ /dev/null @@ -1,31 +0,0 @@ -class Solution { - public int bagOfTokensScore(int[] tokens, int P) { - Arrays.sort(tokens); - int start = 0; - int end = tokens.length - 1; - int numOfPoints = 0; - int maxPoint = 0; - - while (start <= end) { - if (P >= tokens[start]) { - P -= tokens[start]; - start++; - numOfPoints++; - } - else { - if (numOfPoints > 0) { - numOfPoints--; - P += tokens[end]; - end--; - } - else { - break; - } - } - - maxPoint = Math.max(numOfPoints, maxPoint); - } - - return maxPoint; - } -} diff --git a/Contests/Weekly Contest 112/Minimum Increment to Make Array Unique.java b/Contests/Weekly Contest 112/Minimum Increment to Make Array Unique.java deleted file mode 100644 index 983f6d29..00000000 --- a/Contests/Weekly Contest 112/Minimum Increment to Make Array Unique.java +++ /dev/null @@ -1,19 +0,0 @@ -class Solution { - public int minIncrementForUnique(int[] arr) { - int count = 0; - - Arrays.sort(arr); - int previous = Integer.MIN_VALUE; - - for (int i=0; i= arr[i]) { - count += previous - arr[i] == 0 ? 1 : previous + 1 - arr[i]; - arr[i] = previous + 1; - } - - previous = arr[i]; - } - - return count; - } -} diff --git a/Contests/Weekly Contest 112/Most Stones Removed with Same Row or Column.java b/Contests/Weekly Contest 112/Most Stones Removed with Same Row or Column.java deleted file mode 100644 index 916ceeb5..00000000 --- a/Contests/Weekly Contest 112/Most Stones Removed with Same Row or Column.java +++ /dev/null @@ -1,44 +0,0 @@ -class Solution { - public int count = 0; - public int removeStones(int[][] stones) { - Map map = new HashMap<>(); - count = stones.length; - - for (int[] stone : stones) { - String key = stone[0] + " " + stone[1]; - map.put(key, key); - } - - for (int[] stone : stones) { - String key = stone[0] + " " + stone[1]; - for (int[] stone2 : stones) { - if (stone2[0] == stone[0] || stone2[1] == stone[1]) { - String key2 = stone2[0] + " " + stone2[1]; - union(map, key, key2); - } - } - } - - return stones.length - count; - } - - private void union(Map map, String s1, String s2) { - String r1 = find(map, s1); - String r2 = find(map, s2); - - if (r1.equals(r2)) { - return; - } - - map.put(r1, r2); - count--; - } - - private String find(Map map, String s) { - if (!map.get(s).equals(s)) { - map.put(s, find(map, map.get(s))); - } - - return map.get(s); - } -} diff --git a/Contests/Weekly Contest 112/Validate Stack Sequences.java b/Contests/Weekly Contest 112/Validate Stack Sequences.java deleted file mode 100644 index c90d9957..00000000 --- a/Contests/Weekly Contest 112/Validate Stack Sequences.java +++ /dev/null @@ -1,30 +0,0 @@ -class Solution { - public boolean validateStackSequences(int[] pushed, int[] popped) { - Stack stack = new Stack<>(); - - int i = 0; - int j = 0; - - while (i < pushed.length || j < popped.length) { - if (stack.isEmpty() || stack.peek() != popped[j]) { - if (i < pushed.length) { - stack.push(pushed[i++]); - } - else { - return false; - } - } - else { - if (j < popped.length && stack.peek() == popped[j]) { - stack.pop(); - j++; - } - else { - return false; - } - } - } - - return true; - } -} diff --git a/Contests/Weekly Contest 113/Flip Equivalent Binary Trees.java b/Contests/Weekly Contest 113/Flip Equivalent Binary Trees.java deleted file mode 100644 index 9b025770..00000000 --- a/Contests/Weekly Contest 113/Flip Equivalent Binary Trees.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public boolean flipEquiv(TreeNode root1, TreeNode root2) { - if (root1 == null) { - return root2 == null; - } - - if (root2 == null) { - return root1 == null; - } - - if (root1.val != root2.val) { - return false; - } - - return (flipEquiv(root1.left, root2.left) && flipEquiv(root1.right, root2.right) || - flipEquiv(root1.left, root2.right) && flipEquiv(root1.right, root2.left)); - } -} diff --git a/Contests/Weekly Contest 113/Largest Time for Given Digits.java b/Contests/Weekly Contest 113/Largest Time for Given Digits.java deleted file mode 100644 index 7a645e07..00000000 --- a/Contests/Weekly Contest 113/Largest Time for Given Digits.java +++ /dev/null @@ -1,57 +0,0 @@ -class Solution { - public String largestTimeFromDigits(int[] arr) { - List permutations = permuteUnique(arr); - String maxStr = ""; - - for (String str : permutations) { - if (isValid(str)) { - if (maxStr.length() == 0) { - maxStr = str; - } - else if (maxStr.compareTo(str) < 0) { - maxStr = str; - } - } - } - - return maxStr.length() > 0 ? maxStr.substring(0, 2) + ":" + maxStr.substring(2) : maxStr; - } - - private boolean isValid(String str) { - int left = Integer.parseInt(str.substring(0, 2)); - int right = Integer.parseInt(str.substring(2)); - - return left >= 0 && left <= 23 && right >= 0 && right <= 59; - } - - private List permuteUnique(int[] nums) { - List ans = new ArrayList<>(); - Arrays.sort(nums); - permuteHelper(nums, new ArrayList<>(), ans, new boolean[nums.length]); - return new ArrayList<>(ans); - } - - private void permuteHelper(int[] nums, List list, List ans, boolean[] used) { - if (list.size() == nums.length) { - ans.add(list.stream().map(n -> String.valueOf(n)).collect(Collectors.joining(""))); - } - else { - for (int i=0; i 0 && nums[i] == nums[i-1] && !used[i-1])) { - continue; - } - - used[i] = true; - list.add(nums[i]); - - // Explore - permuteHelper(nums, list, ans, used); - - // Un-choose - used[i] = false; - list.remove(list.size()-1); - } - } - } -} diff --git a/Contests/Weekly Contest 113/Reveal Cards In Increasing Order.java b/Contests/Weekly Contest 113/Reveal Cards In Increasing Order.java deleted file mode 100644 index b2aed465..00000000 --- a/Contests/Weekly Contest 113/Reveal Cards In Increasing Order.java +++ /dev/null @@ -1,22 +0,0 @@ -class Solution { - public int[] deckRevealedIncreasing(int[] deck) { - int n = deck.length; - int[] ans = new int[n]; - Deque deque = new LinkedList<>(); - Arrays.sort(deck); - deque.addFirst(deck[n-1]); - - for (int i=n-2; i>=0; i--) { - int temp = deque.removeLast(); - deque.addFirst(temp); - deque.addFirst(deck[i]); - } - - int idx = 0; - while (!deque.isEmpty()) { - ans[idx++] = deque.pollFirst(); - } - - return ans; - } -} diff --git a/Contests/Weekly Contest 115/Check Completeness of a Binary Tree.java b/Contests/Weekly Contest 115/Check Completeness of a Binary Tree.java deleted file mode 100644 index 33573b90..00000000 --- a/Contests/Weekly Contest 115/Check Completeness of a Binary Tree.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public boolean isCompleteTree(TreeNode root) { - if (root == null) { - return true; - } - int numOfNodes = getNumOfNodes(root); - return isCompleteTreeHelper(root, 0, numOfNodes); - } - - private boolean isCompleteTreeHelper(TreeNode root, int curr, int numOfNodes) { - if (root == null) { - return true; - } - - if (curr >= numOfNodes) { - return false; - } - - return isCompleteTreeHelper(root.left, 2 * curr + 1, numOfNodes) && isCompleteTreeHelper(root.right, 2 * curr + 2, numOfNodes); - } - - private int getNumOfNodes(TreeNode root) { - if (root == null) { - return 0; - } - - return 1 + getNumOfNodes(root.left) + getNumOfNodes(root.right); - } -} diff --git a/Contests/Weekly Contest 126/Check If Word Is Valid After Substitutions.java b/Contests/Weekly Contest 126/Check If Word Is Valid After Substitutions.java deleted file mode 100644 index dc030951..00000000 --- a/Contests/Weekly Contest 126/Check If Word Is Valid After Substitutions.java +++ /dev/null @@ -1,21 +0,0 @@ -class Solution { - public boolean isValid(String S) { - Stack stack = new Stack<>(); - for (char c : S.toCharArray()) { - if (c == 'a' || c == 'b') { - stack.push(c); - } - else { - if (stack.isEmpty() || stack.pop() != 'b') { - return false; - } - - if (stack.isEmpty() || stack.pop() != 'a') { - return false; - } - } - } - - return stack.size() == 0; - } -} diff --git a/Contests/Weekly Contest 126/Find Common Characters.java b/Contests/Weekly Contest 126/Find Common Characters.java deleted file mode 100644 index b0fea474..00000000 --- a/Contests/Weekly Contest 126/Find Common Characters.java +++ /dev/null @@ -1,30 +0,0 @@ -class Solution { - public List commonChars(String[] A) { - int[] mainCounter = new int[26]; - Arrays.fill(mainCounter, Integer.MAX_VALUE); - - for (String str : A) { - int[] counter = new int[26]; - for (char c : str.toCharArray()) { - counter[c - 'a']++; - } - - for (int i = 0; i < 26; i++) { - mainCounter[i] = Math.min(mainCounter[i], counter[i]); - } - } - - List list = new ArrayList<>(); - - for (int i = 0; i < 26; i++) { - int count = mainCounter[i]; - char c = (char) (97 + i); - - while (count-- > 0) { - list.add(String.valueOf(c)); - } - } - - return list; - } -} diff --git a/Contests/Weekly Contest 126/Max Consecutive Ones III.java b/Contests/Weekly Contest 126/Max Consecutive Ones III.java deleted file mode 100644 index 49349bd8..00000000 --- a/Contests/Weekly Contest 126/Max Consecutive Ones III.java +++ /dev/null @@ -1,31 +0,0 @@ -class Solution { - public int longestOnes(int[] A, int K) { - int slow = 0; - int fast = 0; - int count = 0; - int end = A.length; - int maxLen = 0; - - while (fast < end) { - if (A[fast] != 1) { - count++; - } - - while (count > K && slow < end) { - if (A[slow] == 0) { - count--; - } - - slow++; - } - - fast++; - - if (fast - slow > maxLen) { - maxLen = fast - slow; - } - } - - return maxLen; - } -} diff --git a/Contests/Weekly Contest 127/Clumsy Factorial.java b/Contests/Weekly Contest 127/Clumsy Factorial.java deleted file mode 100644 index 391ede85..00000000 --- a/Contests/Weekly Contest 127/Clumsy Factorial.java +++ /dev/null @@ -1,59 +0,0 @@ -class Solution { - public int clumsy(int N) { - if (N <= 1) { - return N; - } - - char[] oper = {'*', '/', '+', '-'}; - int idx = 0; - - StringBuilder sb = new StringBuilder(); - while (N > 0) { - sb.append(N).append(" ").append(oper[idx++]).append(" "); - if (idx > 3) { - idx = 0; - } - - N--; - } - - return basicCalculator(sb.toString().substring(0, sb.length() - 2)); - } - - private int basicCalculator(String s) { - int num = 0; - char sign = '+'; - Stack stack = new Stack<>(); - - for (int i = 0; i < s.length(); i++) { - if (Character.isDigit(s.charAt(i))) { - num = num * 10 + Character.getNumericValue(s.charAt(i)); - } - - if (!Character.isDigit(s.charAt(i)) && s.charAt(i) != ' ' || i == s.length() - 1) { - if (sign == '+') { - stack.push(num); - } - else if (sign == '-') { - stack.push(-num); - } - else if (sign == '*') { - stack.push(stack.pop() * num); - } - else { - stack.push(stack.pop() / num); - } - - sign = s.charAt(i); - num = 0; - } - } - - int res = 0; - while (!stack.isEmpty()) { - res += stack.pop(); - } - - return res; - } -} diff --git a/Contests/Weekly Contest 127/Construct Binary Search Tree from Preorder Traversal.java b/Contests/Weekly Contest 127/Construct Binary Search Tree from Preorder Traversal.java deleted file mode 100644 index 276ff05d..00000000 --- a/Contests/Weekly Contest 127/Construct Binary Search Tree from Preorder Traversal.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - int idx; - public TreeNode bstFromPreorder(int[] preorder) { - idx = 0; - return bstFromPreorderHelper(preorder, preorder[0], Integer.MIN_VALUE, Integer.MAX_VALUE); - } - - private TreeNode bstFromPreorderHelper(int[] preorder, int key, int min, int max) { - if (idx >= preorder.length) { - return null; - } - - TreeNode root = null; - - if (preorder[idx] > min && preorder[idx] < max) { - root = new TreeNode(key); - idx++; - - if (idx < preorder.length) { - root.left = bstFromPreorderHelper(preorder, preorder[idx], min, key); - - if (idx < preorder.length) { - root.right = bstFromPreorderHelper(preorder, preorder[idx], key, max); - } - } - } - - return root; - } -} diff --git a/Contests/Weekly Contest 127/Maximize Sum Of Array After K Negations.java b/Contests/Weekly Contest 127/Maximize Sum Of Array After K Negations.java deleted file mode 100644 index a4db5a84..00000000 --- a/Contests/Weekly Contest 127/Maximize Sum Of Array After K Negations.java +++ /dev/null @@ -1,23 +0,0 @@ -class Solution { - public int largestSumAfterKNegations(int[] A, int K) { - PriorityQueue pq = new PriorityQueue<>(); - - for (int num : A) { - pq.add(num); - } - - while (K-- > 0) { - int popped = pq.poll(); - popped *= -1; - - pq.add(popped); - } - - int sum = 0; - while (!pq.isEmpty()) { - sum += pq.poll(); - } - - return sum; - } -} diff --git a/Contests/Weekly Contest 127/Minimum Domino Rotations For Equal Row.java b/Contests/Weekly Contest 127/Minimum Domino Rotations For Equal Row.java deleted file mode 100644 index c9908513..00000000 --- a/Contests/Weekly Contest 127/Minimum Domino Rotations For Equal Row.java +++ /dev/null @@ -1,25 +0,0 @@ -class Solution { - public int minDominoRotations(int[] A, int[] B) { - int[] aCount = new int[7]; - int[] bCount = new int[7]; - int[] sameCount = new int[7]; - - for (int i = 0; i < A.length; i++) { - if (A[i] == B[i]) { - sameCount[A[i]]++; - } - else { - aCount[A[i]]++; - bCount[B[i]]++; - } - } - - for (int i = 1; i <= 6; i++) { - if (aCount[i] + bCount[i] + sameCount[i] == A.length) { - return sameCount[i] == A.length ? 0 : Math.min(aCount[i], bCount[i]); - } - } - - return -1; - } -} diff --git a/Contests/Weekly Contest 129/Best Sightseeing Pair.java b/Contests/Weekly Contest 129/Best Sightseeing Pair.java deleted file mode 100644 index 173b530d..00000000 --- a/Contests/Weekly Contest 129/Best Sightseeing Pair.java +++ /dev/null @@ -1,13 +0,0 @@ -class Solution { - public int maxScoreSightseeingPair(int[] A) { - int maxVal = 0; - int currMax = 0; - - for (int spot : A) { - maxVal = Math.max(maxVal, currMax + spot); - currMax = Math.max(spot, currMax) - 1; - } - - return maxVal; - } -} diff --git a/Contests/Weekly Contest 129/Binary String With Substrings Representing 1 To N.java b/Contests/Weekly Contest 129/Binary String With Substrings Representing 1 To N.java deleted file mode 100644 index 179b0ec2..00000000 --- a/Contests/Weekly Contest 129/Binary String With Substrings Representing 1 To N.java +++ /dev/null @@ -1,15 +0,0 @@ -class Solution { - public boolean queryString(String S, int N) { - - int num = N; - while (num >= N / 2) { - if (S.indexOf(Integer.toBinaryString(num)) == -1) { - return false; - } - - num--; - } - - return true; - } -} diff --git a/Contests/Weekly Contest 129/Partition Array Into Three Parts With Equal Sum.java b/Contests/Weekly Contest 129/Partition Array Into Three Parts With Equal Sum.java deleted file mode 100644 index b325e556..00000000 --- a/Contests/Weekly Contest 129/Partition Array Into Three Parts With Equal Sum.java +++ /dev/null @@ -1,30 +0,0 @@ -class Solution { - public boolean canThreePartsEqualSum(int[] A) { - int totalSum = 0; - for (int num : A) { - totalSum += num; - } - - if (totalSum % 3 != 0) { - return false; - } - - int singlePartitionSum = totalSum / 3; - int idx = 0; - int len = A.length; - int currPartitionSum = 0; - int count = 0; - - while (idx < len) { - currPartitionSum += A[idx]; - if (currPartitionSum == singlePartitionSum) { - count++; - currPartitionSum = 0; - } - - idx++; - } - - return count == 3; - } -} diff --git a/Contests/Weekly Contest 129/Smallest Integer Divisible by K.java b/Contests/Weekly Contest 129/Smallest Integer Divisible by K.java deleted file mode 100644 index aba8f5e3..00000000 --- a/Contests/Weekly Contest 129/Smallest Integer Divisible by K.java +++ /dev/null @@ -1,17 +0,0 @@ -class Solution { - public int smallestRepunitDivByK(int K) { - if (K % 2 == 0 || K % 5 == 0) { - return -1; - } - - int rem = 0; - for (int i = 1; i <= K; i++) { - rem = (rem * 10 + 1) % K; - if (rem == 0) { - return i; - } - } - - return -1; - } -} diff --git a/Contests/Weekly Contest 131/Camelcase Matching.java b/Contests/Weekly Contest 131/Camelcase Matching.java deleted file mode 100644 index 2313a4ee..00000000 --- a/Contests/Weekly Contest 131/Camelcase Matching.java +++ /dev/null @@ -1,43 +0,0 @@ -class Solution { - public List camelMatch(String[] queries, String pattern) { - List ans = new ArrayList<>(); - - for (String query : queries) { - ans.add(check(query, pattern)); - } - - return ans; - } - - private boolean check(String query, String pattern) { - int qIdx = 0; - int pIdx = 0; - int qLen = query.length(); - int pLen = pattern.length(); - - while (qIdx < qLen && pIdx < pLen) { - if (query.charAt(qIdx) == pattern.charAt(pIdx)) { - qIdx++; - pIdx++; - } - else { - if (Character.isUpperCase(query.charAt(qIdx))) { - return false; - } - else { - qIdx++; - } - } - } - - while (qIdx < qLen) { - if (Character.isUpperCase(query.charAt(qIdx))) { - return false; - } - - qIdx++; - } - - return pIdx == pLen; - } -} diff --git a/Contests/Weekly Contest 131/Remove Outermost Parentheses.java b/Contests/Weekly Contest 131/Remove Outermost Parentheses.java deleted file mode 100644 index dfff44c7..00000000 --- a/Contests/Weekly Contest 131/Remove Outermost Parentheses.java +++ /dev/null @@ -1,22 +0,0 @@ -class Solution { - public String removeOuterParentheses(String S) { - StringBuilder sb = new StringBuilder(); - int count = 0; - int prev = 0; - - for (int i = 0; i < S.length(); i++) { - if (S.charAt(i) == '(') { - count++; - } - else { - count--; - if (count == 0) { - sb.append(S.substring(prev + 1, i)); - prev = i + 1; - } - } - } - - return sb.toString(); - } -} diff --git a/Contests/Weekly Contest 131/Sum of Root To Leaf Binary Numbers.java b/Contests/Weekly Contest 131/Sum of Root To Leaf Binary Numbers.java deleted file mode 100644 index 8b630ccd..00000000 --- a/Contests/Weekly Contest 131/Sum of Root To Leaf Binary Numbers.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public int sumRootToLeaf(TreeNode root) { - return dfsHelper(root, 0); - } - - private int MOD = 1000000007; - - private int dfsHelper(TreeNode root, int curr) { - if (root == null) { - return curr % MOD; - } - - curr = (curr * 2 + root.val) % MOD; - - if (root.left == null && root.right == null) { - return curr % MOD; - } - - int sum = 0; - - if (root.left != null) { - sum += dfsHelper(root.left, curr); - } - - if (root.right != null) { - sum += dfsHelper(root.right, curr); - } - - return sum % MOD; - } -} diff --git a/Contests/Weekly Contest 132/Divisor Game.java b/Contests/Weekly Contest 132/Divisor Game.java deleted file mode 100644 index 8a30b499..00000000 --- a/Contests/Weekly Contest 132/Divisor Game.java +++ /dev/null @@ -1,5 +0,0 @@ -class Solution { - public boolean divisorGame(int N) { - return N % 2 == 0; - } -} diff --git a/Contests/Weekly Contest 132/Longest Arithmetic Sequence.java b/Contests/Weekly Contest 132/Longest Arithmetic Sequence.java deleted file mode 100644 index 15ad247d..00000000 --- a/Contests/Weekly Contest 132/Longest Arithmetic Sequence.java +++ /dev/null @@ -1,35 +0,0 @@ -class Solution { - public int longestArithSeqLength(int[] A) { - if (A.length <= 1) { - return A.length; - } - - int res = 0; - HashMap[] dp = new HashMap[A.length]; - - for (int i = 0; i < A.length; i++) { - dp[i] = new HashMap<>(); - } - - for (int i = 1; i < A.length; i++) { - int curr = A[i]; - for (int j = 0; j < i; j++) { - int prev = A[j]; - int diff = curr - prev; - - int len = 2; - - if (dp[j].containsKey(diff)) { - len = dp[j].get(diff) + 1; - } - - int currLen = dp[i].getOrDefault(diff, 0); - dp[i].put(diff, Math.max(currLen, len)); - - res = Math.max(res, dp[i].get(diff)); - } - } - - return res; - } -} diff --git a/Contests/Weekly Contest 132/Maximum Difference Between Node and Ancestor.java b/Contests/Weekly Contest 132/Maximum Difference Between Node and Ancestor.java deleted file mode 100644 index ea63ea0d..00000000 --- a/Contests/Weekly Contest 132/Maximum Difference Between Node and Ancestor.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public int maxAncestorDiff(TreeNode root) { - return dfs(root, root.val, root.val); - } - - public int dfs(TreeNode root, int min, int max) { - if (root == null) { - return 0; - } - - int res = Math.max(max - root.val, root.val - min); - max = Math.max(root.val, max); - min = Math.min(root.val, min); - - res = Math.max(res, dfs(root.left, min, max)); - res = Math.max(res, dfs(root.right, min, max)); - - return res; - } -} diff --git a/Easy/1-bit and 2-bit Characters.java b/Easy/1-bit and 2-bit Characters.java index c2031613..f58ff16a 100644 --- a/Easy/1-bit and 2-bit Characters.java +++ b/Easy/1-bit and 2-bit Characters.java @@ -1,20 +1,12 @@ class Solution { public boolean isOneBitCharacter(int[] bits) { int idx = 0; - int n = bits.length; - while (idx < n) { - if (bits[idx] == 1) { - if (idx + 1 == n - 1) { - return false; - } - else { - idx += 2; - } - } - else { + while (idx < bits.length - 1) { + if (bits[idx] != 0) { idx++; } + idx++; } - return true; - } + return idx == bits.length - 1; + } } diff --git a/Easy/A Number After a Double Reversal.java b/Easy/A Number After a Double Reversal.java new file mode 100644 index 00000000..bace60bb --- /dev/null +++ b/Easy/A Number After a Double Reversal.java @@ -0,0 +1,11 @@ +class Solution { + public boolean isSameAfterReversals(int num) { + if (num <= 9) { + return true; + } + if (num % 10 == 0) { + return false; + } + return true; + } +} diff --git a/Easy/Account Balance After Rounded Purchase.java b/Easy/Account Balance After Rounded Purchase.java new file mode 100644 index 00000000..3342d18d --- /dev/null +++ b/Easy/Account Balance After Rounded Purchase.java @@ -0,0 +1,10 @@ +class Solution { + public int accountBalanceAfterPurchase(int purchaseAmount) { + if (purchaseAmount % 10 >= 5) { + purchaseAmount += 10 - purchaseAmount % 10; + } else { + purchaseAmount -= purchaseAmount % 10; + } + return 100 - purchaseAmount; + } +} diff --git a/Easy/Add Binary.java b/Easy/Add Binary.java index b51d82be..d35b471f 100644 --- a/Easy/Add Binary.java +++ b/Easy/Add Binary.java @@ -1,18 +1,19 @@ class Solution { public String addBinary(String a, String b) { - int carry = 0; StringBuilder sb = new StringBuilder(); - int idxA = a.length() - 1; - int idxB = b.length() - 1; - while (idxA >= 0 || idxB >= 0 || carry > 0) { - int temp = ( - (idxA >= 0 ? Character.getNumericValue(a.charAt(idxA--)) : 0) + - (idxB >= 0 ? Character.getNumericValue(b.charAt(idxB--)) : 0) + - carry - ); - carry = temp > 1 ? 1 : 0; - temp = temp > 1 ? (temp == 2 ? 0 : 1) : temp; - sb.append(temp); + int endIdxA = a.length() - 1; + int endIdxB = b.length() - 1; + int carry = 0; + while (endIdxA >= 0 || endIdxB >= 0 || carry > 0) { + int value = carry; + if (endIdxA >= 0) { + value += Character.getNumericValue(a.charAt(endIdxA--)); + } + if (endIdxB >= 0) { + value += Character.getNumericValue(b.charAt(endIdxB--)); + } + sb.append(value % 2); + carry = value / 2; } return sb.reverse().toString(); } diff --git a/Easy/Add Digits.java b/Easy/Add Digits.java index c701c82a..a17de297 100644 --- a/Easy/Add Digits.java +++ b/Easy/Add Digits.java @@ -1,17 +1,13 @@ class Solution { public int addDigits(int num) { - while (String.valueOf(num).length() > 1) { - num = getDigitSum(num); + if (num / 10 == 0) { + return num; } - return num; - } - - private int getDigitSum(int n) { - int newNum = 0; - while (n > 0) { - newNum += n % 10; - n /= 10; + int digitSum = 0; + while (num > 0) { + digitSum += num % 10; + num /= 10; } - return newNum; + return addDigits(digitSum); } } diff --git a/Easy/Add Strings.java b/Easy/Add Strings.java index f229760b..16cf5461 100644 --- a/Easy/Add Strings.java +++ b/Easy/Add Strings.java @@ -1,26 +1,19 @@ class Solution { public String addStrings(String num1, String num2) { - StringBuilder sb = new StringBuilder(); - int idx1 = num1.length() - 1; - int idx2 = num2.length() - 1; int carry = 0; - while (idx1 >= 0 || idx2 >= 0) { - int temp = carry; - if (idx1 >= 0 && idx2 >= 0) { - temp += Character.getNumericValue(num1.charAt(idx1--)) + Character.getNumericValue(num2.charAt(idx2--)); - } - else if (idx1 >= 0 && idx2 < 0) { - temp += Character.getNumericValue(num1.charAt(idx1--)); - } - else { - temp += Character.getNumericValue(num2.charAt(idx2--)); + StringBuilder sb = new StringBuilder(); + int idxOne = num1.length() - 1; + int idxTwo = num2.length() - 1; + while (idxOne >= 0 || idxTwo >= 0 || carry > 0) { + if (idxOne >= 0 && idxTwo >= 0) { + carry += Character.getNumericValue(num1.charAt(idxOne--)) + Character.getNumericValue(num2.charAt(idxTwo--)); + } else if (idxOne >= 0 && idxTwo < 0) { + carry += Character.getNumericValue(num1.charAt(idxOne--)); + } else if (idxOne < 0 && idxTwo >= 0) { + carry += Character.getNumericValue(num2.charAt(idxTwo--)); } - carry = temp > 9 ? 1 : 0; - temp = temp > 9 ? temp % 10 : temp; - sb.append(temp); - } - if (carry > 0) { - sb.append(carry); + sb.append(carry % 10); + carry = carry > 9 ? carry / 10 : 0; } return sb.reverse().toString(); } diff --git a/Easy/Add to Array-Form of Integer.java b/Easy/Add to Array-Form of Integer.java index c1ab95b2..64cbbb31 100644 --- a/Easy/Add to Array-Form of Integer.java +++ b/Easy/Add to Array-Form of Integer.java @@ -1,20 +1,22 @@ class Solution { - public List addToArrayForm(int[] A, int K) { - List list = new ArrayList<>(); - int idx = A.length - 1; - int carry = 0; - while (K > 0 || idx >= 0 || carry > 0) { - int temp = ( - (K > 0 ? K % 10 : 0) + - (idx >= 0 ? A[idx--] : 0) + - carry - ); - K /= 10; - carry = temp > 9 ? temp / 10 : 0; - temp = temp > 9 ? temp % 10 : temp; - list.add(temp); + public List addToArrayForm(int[] num, int k) { + List result = new ArrayList<>(); + int idx = num.length - 1; + int carry = 0; + while (idx >= 0 || k > 0 || carry > 0) { + if (idx >= 0 && k > 0) { + carry += num[idx--] + k % 10; + k /= 10; + } else if (idx >= 0 && k == 0) { + carry += num[idx--]; + } else if (idx < 0 && k > 0) { + carry += k % 10; + k /= 10; + } + result.add(carry % 10); + carry /= 10; + } + Collections.reverse(result); + return result; } - Collections.reverse(list); - return list; - } } diff --git a/Easy/Adjacent Increasing Subarrays Detection I.java b/Easy/Adjacent Increasing Subarrays Detection I.java new file mode 100644 index 00000000..5be82de7 --- /dev/null +++ b/Easy/Adjacent Increasing Subarrays Detection I.java @@ -0,0 +1,20 @@ +class Solution { + public boolean hasIncreasingSubarrays(List nums, int k) { + int n = nums.size(); + for (int i = 0; i <= n - 2 * k; i++) { + if (isStrictlyIncreasing(nums, i, k) && isStrictlyIncreasing(nums, i + k, k)) { + return true; + } + } + return false; + } + + private boolean isStrictlyIncreasing(List nums, int idx, int k) { + for (int start = idx; start < idx + k - 1; start++) { + if (nums.get(start) >= nums.get(start + 1)) { + return false; + } + } + return true; + } +} diff --git a/Easy/Alternating Digit Sum.java b/Easy/Alternating Digit Sum.java new file mode 100644 index 00000000..4505e2e3 --- /dev/null +++ b/Easy/Alternating Digit Sum.java @@ -0,0 +1,18 @@ +class Solution { + public int alternateDigitSum(int n) { + int firstHalf = 0; + int secondHalf = 0; + int count = 0; + while (n > 0) { + secondHalf += n % 10; + n /= 10; + count++; + if (n > 0) { + firstHalf += n % 10; + n /= 10; + count++; + } + } + return count % 2 == 0 ? (firstHalf + -1 * secondHalf) : (secondHalf + -1 * firstHalf); + } +} diff --git a/Easy/Alternating Groups I.java b/Easy/Alternating Groups I.java new file mode 100644 index 00000000..9730d5ea --- /dev/null +++ b/Easy/Alternating Groups I.java @@ -0,0 +1,18 @@ +class Solution { + public int numberOfAlternatingGroups(int[] colors) { + int count = 0; + int n = colors.length; + for (int i = 0; i < n - 2; i++) { + if (colors[i + 1] != colors[i] && colors[i + 1] != colors[i + 2]) { + count++; + } + } + if (colors[n - 2] != colors[n - 1] && colors[n - 2] == colors[0]) { + count++; + } + if (colors[n - 1] != colors[0] && colors[n - 1] == colors[1]) { + count++; + } + return count; + } +} diff --git a/Easy/Ant on the Boundary.java b/Easy/Ant on the Boundary.java new file mode 100644 index 00000000..25e95d0a --- /dev/null +++ b/Easy/Ant on the Boundary.java @@ -0,0 +1,13 @@ +class Solution { + public int returnToBoundaryCount(int[] nums) { + int currPosition = 0; + int count = 0; + for (int num : nums) { + currPosition += num; + if (currPosition == 0) { + count++; + } + } + return count; + } +} diff --git a/Easy/Apple Redistribution into Boxes.java b/Easy/Apple Redistribution into Boxes.java new file mode 100644 index 00000000..d84bd8a8 --- /dev/null +++ b/Easy/Apple Redistribution into Boxes.java @@ -0,0 +1,20 @@ +class Solution { + public int minimumBoxes(int[] apple, int[] capacity) { + int totalApples = 0; + for (int count : apple) { + totalApples += count; + } + Arrays.sort(capacity); + int idx = capacity.length - 1; + int currCapacity = capacity[idx--]; + while (totalApples > 0) { + int applesDeleted = Math.min(currCapacity, totalApples); + totalApples -= applesDeleted; + currCapacity -= applesDeleted; + if (currCapacity == 0 && totalApples > 0) { + currCapacity = capacity[idx--]; + } + } + return capacity.length - idx - 1; + } +} diff --git a/Easy/Apply Operations to an Array.java b/Easy/Apply Operations to an Array.java new file mode 100644 index 00000000..3b2bca86 --- /dev/null +++ b/Easy/Apply Operations to an Array.java @@ -0,0 +1,21 @@ +class Solution { + public int[] applyOperations(int[] nums) { + int n = nums.length; + for (int i = 0; i < n - 1; i++) { + if (nums[i] == nums[i + 1]) { + nums[i] *= 2; + nums[i + 1] = 0; + } + } + int start = 0; + for (int i = 0; i < n; i++) { + if (nums[i] != 0) { + nums[start++] = nums[i]; + } + } + while (start < n) { + nums[start++] = 0; + } + return nums; + } +} diff --git a/Easy/Arranging Coins.java b/Easy/Arranging Coins.java index bf2f70fa..0719ca73 100644 --- a/Easy/Arranging Coins.java +++ b/Easy/Arranging Coins.java @@ -1,14 +1,18 @@ class Solution { public int arrangeCoins(int n) { - int copy = n; - int count = 0; - for (int i = 1; i <= copy && n > 0; i++) { - n -= i; - if (n < 0) { - break; + long left = 1; + long right = n; + while (left <= right) { + long mid = (left + right) / 2; + long sum = mid * (mid + 1) / 2; + if (sum == n) { + return (int) mid; + } else if (sum > n) { + right = mid - 1; + } else { + left = mid + 1; } - count++; } - return count; + return (int) right; } } diff --git a/Easy/Array Partition I.java b/Easy/Array Partition I.java index 8e6012c2..9c263d99 100644 --- a/Easy/Array Partition I.java +++ b/Easy/Array Partition I.java @@ -1,18 +1,18 @@ class Solution { public int arrayPairSum(int[] nums) { - int[] arr = new int[20001]; + int[] counter = new int[20001]; for (int num : nums) { - arr[num + 10000]++; + counter[num + 10000]++; } int sum = 0; - boolean odd = true; - for (int i = 0; i < arr.length; i++) { - while (arr[i] > 0) { - if (odd) { + boolean pickFirst = true; + for (int i = 0; i < counter.length; i++) { + while (counter[i] > 0) { + if (pickFirst) { sum += i - 10000; } - odd = !odd; - arr[i]--; + pickFirst = !pickFirst; + counter[i]--; } } return sum; diff --git a/Easy/Assign Cookies.java b/Easy/Assign Cookies.java index 164c2bfe..32b09bf6 100644 --- a/Easy/Assign Cookies.java +++ b/Easy/Assign Cookies.java @@ -1,17 +1,13 @@ class Solution { - public int findContentChildren(int[] g, int[] s) { - Arrays.sort(g); - Arrays.sort(s); - int count = 0; - for (int i=0;i= greed[idx]) { + idx++; } } - return count; + return idx; } } diff --git a/Easy/Average Salary Excluding the Minimum and Maximum Salary.java b/Easy/Average Salary Excluding the Minimum and Maximum Salary.java index 08d8663e..1d4d872c 100644 --- a/Easy/Average Salary Excluding the Minimum and Maximum Salary.java +++ b/Easy/Average Salary Excluding the Minimum and Maximum Salary.java @@ -1,15 +1,13 @@ class Solution { - public double average(int[] salary) { - int minSalary = salary[0]; - int maxSalary = salary[0]; - int n = salary.length; - int sum = 0; - for (int i = 0; i < n; i++) { - sum += salary[i]; - minSalary = Math.min(minSalary, salary[i]); - maxSalary = Math.max(maxSalary, salary[i]); + public double average(int[] salary) { + int minSalary = salary[0]; + int maxSalary = salary[0]; + double totalSalary = 0; + for (int s : salary) { + minSalary = Math.min(minSalary, s); + maxSalary = Math.max(maxSalary, s); + totalSalary += s; + } + return (totalSalary - minSalary - maxSalary) / (salary.length - 2); } - sum -= (maxSalary + minSalary); - return ((double) sum) / (n - 2); - } } diff --git a/Easy/Average Value of Even Numbers That Are Divisible by Three.java b/Easy/Average Value of Even Numbers That Are Divisible by Three.java new file mode 100644 index 00000000..c0e3274e --- /dev/null +++ b/Easy/Average Value of Even Numbers That Are Divisible by Three.java @@ -0,0 +1,13 @@ +class Solution { + public int averageValue(int[] nums) { + int total = 0; + int count = 0; + for (int num : nums) { + if (num % 2 == 0 && num % 3 == 0) { + total += num; + count++; + } + } + return count == 0 ? 0 : total / count; + } +} diff --git a/Easy/Average of Levels in Binary Tree.java b/Easy/Average of Levels in Binary Tree.java index dad5fc3e..28bd78a2 100644 --- a/Easy/Average of Levels in Binary Tree.java +++ b/Easy/Average of Levels in Binary Tree.java @@ -15,18 +15,15 @@ */ class Solution { public List averageOfLevels(TreeNode root) { - List averages = new ArrayList<>(); - if (root == null) { - return averages; - } + List result = new ArrayList<>(); Queue queue = new LinkedList<>(); queue.add(root); while (!queue.isEmpty()) { - long sum = 0; int size = queue.size(); + double total = 0.0; for (int i = 0; i < size; i++) { TreeNode removed = queue.remove(); - sum += removed.val; + total += removed.val; if (removed.left != null) { queue.add(removed.left); } @@ -34,8 +31,8 @@ public List averageOfLevels(TreeNode root) { queue.add(removed.right); } } - averages.add(((double) sum) / size); + result.add(total / size); } - return averages; + return result; } } diff --git a/Easy/Backspace String Compare.java b/Easy/Backspace String Compare.java index b480d09f..91ef6593 100644 --- a/Easy/Backspace String Compare.java +++ b/Easy/Backspace String Compare.java @@ -1,45 +1,23 @@ class Solution { - public boolean backspaceCompare(String S, String T) { - int i = S.length() - 1; - int j = T.length() - 1; - int skipS = 0; - int skipT = 0; - while (i >= 0 || j >= 0) { - while (i >= 0) { - if (S.charAt(i) == '#') { - skipS++; - i--; - } - else if (skipS > 0) { - skipS--; - i--; - } - else { - break; - } - } - while (j >= 0) { - if (T.charAt(j) == '#') { - skipT++; - j--; - } - else if (skipT > 0) { - skipT--; - j--; + public boolean backspaceCompare(String s, String t) { + return buildBackspaceString(s).equals(buildBackspaceString(t)); + } + + private static String buildBackspaceString(String s) { + Stack stack = new Stack<>(); + for (char c : s.toCharArray()) { + if (c == '#') { + if (!stack.isEmpty()) { + stack.pop(); + } + } else { + stack.push(c); + } } - else { - break; + StringBuilder sb = new StringBuilder(); + for (char c : stack) { + sb.append(c); } - } - if (i >= 0 && j >= 0 && S.charAt(i) != T.charAt(j)) { - return false; - } - if ((i >= 0) != (j >= 0)) { - return false; - } - i--; - j--; + return sb.toString(); } - return true; - } } diff --git a/Easy/Balanced Binary Tree.java b/Easy/Balanced Binary Tree.java index 99084872..fb3ea347 100644 --- a/Easy/Balanced Binary Tree.java +++ b/Easy/Balanced Binary Tree.java @@ -4,23 +4,38 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public boolean isBalanced(TreeNode root) { - if (root == null) return true; - - int lh = height(root.left); - int rh = height(root.right); - - return Math.abs(lh-rh) <= 1 && isBalanced(root.left) && isBalanced(root.right); + public boolean isBalanced(TreeNode root) { + if (root == null) { + return true; } - - public int height(TreeNode root) { - if(root == null) return 0; - - return 1 + Math.max(height(root.left), height(root.right)); + Map map = new HashMap<>(); + int leftHeight = getHeight(root.left, map); + int rightHeight = getHeight(root.right, map); + if (Math.abs(leftHeight - rightHeight) > 1) { + return false; } - + return isBalanced(root.left) && isBalanced(root.right); + } + + private int getHeight(TreeNode root, Map map) { + if (root == null) { + return 0; + } + if (map.containsKey(root)) { + return map.get(root); + } + int height = 1 + Math.max(getHeight(root.left, map), getHeight(root.right, map)); + map.put(root, height); + return height; + } } diff --git a/Easy/Base 7.java b/Easy/Base 7.java index 88c05c8a..8da9a029 100644 --- a/Easy/Base 7.java +++ b/Easy/Base 7.java @@ -1,12 +1,15 @@ class Solution { public String convertToBase7(int num) { - if (num == 0) return "0"; - int temp = Math.abs(num); - StringBuilder sb = new StringBuilder(""); - while (temp > 0) { - sb.append(String.valueOf(temp%7)); - temp /= 7; + StringBuilder sb = new StringBuilder(); + boolean isNegative = num < 0; + num = Math.abs(num); + while (num > 0) { + sb.append(num % 7); + num /= 7; } - return num < 0 ? "-" + sb.reverse().toString() : sb.reverse().toString(); + if (isNegative) { + sb.append('-'); + } + return sb.isEmpty() ? "0" : sb.reverse().toString(); } } diff --git a/Easy/Baseball Game.java b/Easy/Baseball Game.java index eb499246..87e2eea4 100644 --- a/Easy/Baseball Game.java +++ b/Easy/Baseball Game.java @@ -1,28 +1,25 @@ class Solution { public int calPoints(String[] ops) { Stack stack = new Stack<>(); - int sum = 0; + int totalScore = 0; for (String op : ops) { - if (op.equals("+")) { - int prev = stack.pop(); - int prevToPrev = stack.peek(); - int newScore = prev + prevToPrev; - sum += newScore; - stack.push(prev); + if (op.equals("D")) { + int newScore = 2 * stack.peek(); + totalScore += newScore; stack.push(newScore); - } - else if (op.equals("C")) { - sum -= stack.pop(); - } - else if (op.equals("D")) { - sum += stack.peek() * 2; - stack.push(stack.peek() * 2); - } - else { + } else if (op.equals("C")) { + totalScore -= stack.pop(); + } else if (op.equals("+")) { + int scoreTwo = stack.pop(); + int newScore = scoreTwo + stack.peek(); + stack.push(scoreTwo); + stack.push(newScore); + totalScore += newScore; + } else { stack.push(Integer.parseInt(op)); - sum += stack.peek(); + totalScore += Integer.parseInt(op); } } - return sum; + return totalScore; } } diff --git a/Easy/Best Poker Hand.java b/Easy/Best Poker Hand.java new file mode 100644 index 00000000..3a648cc1 --- /dev/null +++ b/Easy/Best Poker Hand.java @@ -0,0 +1,28 @@ +class Solution { + public String bestHand(int[] ranks, char[] suits) { + char suitCard = '-'; + for (int i = 0; i < suits.length; i++) { + if (suitCard != '-' && suitCard != suits[i]) { + break; + } + if (suitCard == '-') { + suitCard = suits[i]; + } + if (i == suits.length - 1) { + return "Flush"; + } + } + Map frequencyMap = new HashMap<>(); + boolean pairFound = false; + for (int rank : ranks) { + frequencyMap.put(rank, frequencyMap.getOrDefault(rank, 0) + 1); + if (frequencyMap.get(rank) == 3) { + return "Three of a Kind"; + } + if (frequencyMap.get(rank) == 2) { + pairFound = true; + } + } + return pairFound ? "Pair" : "High Card"; + } +} diff --git a/Easy/Best Time to Buy and Sell Stock.java b/Easy/Best Time to Buy and Sell Stock.java index a30f4e9b..08df1870 100644 --- a/Easy/Best Time to Buy and Sell Stock.java +++ b/Easy/Best Time to Buy and Sell Stock.java @@ -1,14 +1,12 @@ class Solution { public int maxProfit(int[] prices) { + int minPrice = prices[0]; int maxProfit = 0; - int currMin = Integer.MAX_VALUE; for (int price : prices) { - if (price > currMin) { - maxProfit = Math.max(maxProfit, price - currMin); - } - else { - currMin = price; + if (price < minPrice) { + minPrice = price; } + maxProfit = Math.max(maxProfit, price - minPrice); } return maxProfit; } diff --git a/Easy/Best time to buy & sell a stock II.java b/Easy/Best time to buy & sell a stock II.java deleted file mode 100644 index cfe8e938..00000000 --- a/Easy/Best time to buy & sell a stock II.java +++ /dev/null @@ -1,16 +0,0 @@ -class Solution { - public int maxProfit(int[] prices) { - int lowest = Integer.MAX_VALUE; - int profit = 0; - for (int i = 0; i < prices.length; i++) { - if (prices[i] > lowest) { - profit += prices[i] - lowest; - lowest = prices[i]; - } - else { - lowest = prices[i]; - } - } - return profit; - } -} diff --git a/Easy/Binary Gap.java b/Easy/Binary Gap.java index c86d7908..fcd7178f 100644 --- a/Easy/Binary Gap.java +++ b/Easy/Binary Gap.java @@ -1,21 +1,19 @@ class Solution { - public int binaryGap(int N) { - char[] binValues = Integer.toBinaryString(N).toCharArray(); - int oneIndex = -1; - int maxDistance = 0; - - for (int i=0; i 0) { + int rem = n % 2; + n /= 2; + if (rem == 1) { + if (lastOnePosition != -1) { + maxGap = Math.max(maxGap, currPosition - lastOnePosition); } + lastOnePosition = currPosition; } + currPosition++; } - - return maxDistance; + return maxGap; } } diff --git a/Easy/Binary Number with Alternating Bits.java b/Easy/Binary Number with Alternating Bits.java index 8b0bde44..82288dd5 100644 --- a/Easy/Binary Number with Alternating Bits.java +++ b/Easy/Binary Number with Alternating Bits.java @@ -1,12 +1,15 @@ class Solution { - public boolean hasAlternatingBits(int n) { - int prev = n%2; - n /=2; - while (n>0) { - if (n%2 == prev) return false; - prev = n%2; - n /= 2; - } - return true; + public boolean hasAlternatingBits(int n) { + Integer prev = null; + while (n > 0) { + int rem = n % 2; + n /= 2; + if (prev == null || prev != rem) { + prev = rem; + } else { + return false; + } } + return true; + } } diff --git a/Easy/Binary Search.java b/Easy/Binary Search.java index 8fac5829..0acaa8aa 100644 --- a/Easy/Binary Search.java +++ b/Easy/Binary Search.java @@ -1,17 +1,15 @@ class Solution { public int search(int[] nums, int target) { - int left = 0; - int right = nums.length - 1; - while (left <= right) { - int mid = (left + right) / 2; + int start = 0; + int end = nums.length - 1; + while (start <= end) { + int mid = (start + end) / 2; if (nums[mid] == target) { return mid; - } - else if (nums[mid] > target) { - right = mid - 1; - } - else { - left = mid + 1; + } else if (nums[mid] < target) { + start = mid + 1; + } else { + end = mid - 1; } } return -1; diff --git a/Easy/Binary Tree Inorder Traversal.java b/Easy/Binary Tree Inorder Traversal.java new file mode 100644 index 00000000..d17cf649 --- /dev/null +++ b/Easy/Binary Tree Inorder Traversal.java @@ -0,0 +1,38 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public List inorderTraversal(TreeNode root) { + if (root == null) { + return List.of(); + } + Stack stack = new Stack<>(); + while (root != null) { + stack.push(root); + root = root.left; + } + List result = new ArrayList<>(); + while (!stack.isEmpty()) { + TreeNode removed = stack.pop(); + result.add(removed.val); + TreeNode rightNode = removed.right; + while (rightNode != null) { + stack.push(rightNode); + rightNode = rightNode.left; + } + } + return result; + } +} diff --git a/Easy/Binary Tree Paths.java b/Easy/Binary Tree Paths.java index 08dfef94..72739836 100644 --- a/Easy/Binary Tree Paths.java +++ b/Easy/Binary Tree Paths.java @@ -4,32 +4,33 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - List list; public List binaryTreePaths(TreeNode root) { - list = new ArrayList<>(); - if (root == null) { - return list; - } - helper(root, new StringBuilder()); - return list; + List result = new ArrayList<>(); + helper(root, result, new StringBuilder()); + return result; } - private void helper(TreeNode root, StringBuilder sb) { + private void helper(TreeNode root, List result, StringBuilder path) { if (root == null) { return; } + path.append(root.val); if (root.left == null && root.right == null) { - sb.append(root.val); - list.add(sb.toString()); - } - else { - sb.append(root.val).append("->"); - helper(root.left, new StringBuilder(sb.toString())); - helper(root.right, new StringBuilder(sb.toString())); + result.add(path.toString()); + } else { + path.append("->"); + helper(root.left, result, new StringBuilder(path)); + helper(root.right, result, new StringBuilder(path)); } } } diff --git a/Easy/Binary Tree Postorder Traversal.java b/Easy/Binary Tree Postorder Traversal.java new file mode 100644 index 00000000..4e839ba8 --- /dev/null +++ b/Easy/Binary Tree Postorder Traversal.java @@ -0,0 +1,34 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public List postorderTraversal(TreeNode root) { + List result = new ArrayList<>(); + Stack stack = new Stack<>(); + TreeNode node = root; + while (!stack.isEmpty() || node != null) { + if (node != null) { + stack.push(node); + result.add(node.val); + node = node.right; + } else { + TreeNode removed = stack.pop(); + node = removed.left; + } + } + Collections.reverse(result); + return result; + } +} diff --git a/Easy/Binary Watch.java b/Easy/Binary Watch.java new file mode 100644 index 00000000..454f9b6c --- /dev/null +++ b/Easy/Binary Watch.java @@ -0,0 +1,13 @@ +class Solution { + public List readBinaryWatch(int turnedOn) { + return IntStream.range(0, 12) + .boxed() + .flatMap( + h -> IntStream.range(0, 60) + .boxed() + .filter(s -> Integer.bitCount(h) + Integer.bitCount(s) == turnedOn) + .map(m -> String.format("%d:%02d", h, m)) + ) + .collect(Collectors.toList()); + } +} diff --git a/Easy/Bold Words in String.java b/Easy/Bold Words in String.java deleted file mode 100644 index 16d3e6d3..00000000 --- a/Easy/Bold Words in String.java +++ /dev/null @@ -1,30 +0,0 @@ -class Solution { - public String boldWords(String[] words, String S) { - int N = S.length(); - boolean[] mask = new boolean[N]; - for (int i = 0; i < N; ++i) { - for (String word: words) search: { - for (int k = 0; k < word.length(); ++k) { - if (k + i >= S.length() || S.charAt(k + i) != word.charAt(k)) { - break search; - } - } - for (int j = i; j < i + word.length(); ++j) { - mask[j] = true; - } - } - } - StringBuilder ans = new StringBuilder(); - int anchor = 0; - for (int i = 0; i < N; ++i) { - if (mask[i] && (i == 0 || !mask[i - 1])) { - ans.append(""); - } - ans.append(S.charAt(i)); - if (mask[i] && (i == N - 1 || !mask[i + 1])) { - ans.append(""); - } - } - return ans.toString(); - } -} diff --git a/Easy/Buddy Strings.java b/Easy/Buddy Strings.java index c6cdc61a..f34ecf35 100644 --- a/Easy/Buddy Strings.java +++ b/Easy/Buddy Strings.java @@ -1,44 +1,32 @@ class Solution { - public boolean buddyStrings(String A, String B) { - if (A.length() != B.length()) { - return false; - } - char requiredChar = '-'; - char mismatchChar = '-'; - int[] counter = new int[26]; - for (int i = 0; i < A.length(); i++) { - if (A.charAt(i) != B.charAt(i)) { - // Already done one swap hence cannot do any more swaps - if (requiredChar == '_') { - return false; - } - if (requiredChar == '-') { - requiredChar = B.charAt(i); - mismatchChar = A.charAt(i); - } - else { - // Check if swap is possible from previous mismatch - if (B.charAt(i) == mismatchChar && A.charAt(i) == requiredChar) { - requiredChar = '_'; - } - else { + + private static final int SWAP_DONE_IDX = Integer.MIN_VALUE; + + public boolean buddyStrings(String s, String goal) { + if (s.length() != goal.length()) { return false; - } } - } - else { - counter[A.charAt(i) - 'a']++; - } - } - if (mismatchChar != '-') { - return requiredChar == '_'; - } - // Check if we have more than 1 occurrence of same characters. We can swap them to fulfil the condition - for (int i = 0; i < 26; i++) { - if (counter[i] > 1) { - return true; - } + int swapIdx = -1; + Set set = new HashSet<>(); + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == goal.charAt(i)) { + set.add(s.charAt(i)); + continue; + } + if (s.charAt(i) != goal.charAt(i)) { + if (swapIdx == SWAP_DONE_IDX) { + return false; + } + if (swapIdx == -1) { + swapIdx = i; + continue; + } + if (!(s.charAt(swapIdx) == goal.charAt(i) && s.charAt(i) == goal.charAt(swapIdx))) { + return false; + } + swapIdx = SWAP_DONE_IDX; + } + } + return (swapIdx != -1 && swapIdx == SWAP_DONE_IDX) || (swapIdx == -1 && set.size() < s.length()); } - return false; - } } diff --git a/Easy/Build Array from Permutation.java b/Easy/Build Array from Permutation.java new file mode 100644 index 00000000..6a2a6dec --- /dev/null +++ b/Easy/Build Array from Permutation.java @@ -0,0 +1,12 @@ +class Solution { + public int[] buildArray(int[] nums) { + int n = nums.length; + for (int i = 0; i < n; i++) { + nums[i] = nums[i] + n * (nums[nums[i]] % n); + } + for (int i = 0; i < n; i++) { + nums[i] = nums[i] / n; + } + return nums; + } +} diff --git a/Easy/Build an Array With Stack Operations.java b/Easy/Build an Array With Stack Operations.java deleted file mode 100644 index c3a57156..00000000 --- a/Easy/Build an Array With Stack Operations.java +++ /dev/null @@ -1,20 +0,0 @@ -class Solution { - public List buildArray(int[] target, int n) { - List ans = new ArrayList<>(); - final String PUSH = "Push"; - final String POP = "Pop"; - int idx = 0; - int curr = 1; - while (idx < target.length) { - ans.add(PUSH); - if (target[idx] == curr) { - idx++; - } - else { - ans.add(POP); - } - curr++; - } - return ans; - } -} diff --git a/Easy/Button with Longest Push Time.java b/Easy/Button with Longest Push Time.java new file mode 100644 index 00000000..650bb1e4 --- /dev/null +++ b/Easy/Button with Longest Push Time.java @@ -0,0 +1,18 @@ +class Solution { + public int buttonWithLongestTime(int[][] events) { + int maxTime = 0; + int resultIdx = 0; + int prevTime = 0; + for (int i = 0; i < events.length; i++) { + int timePressed = events[i][1] - prevTime; + if (timePressed > maxTime) { + maxTime = timePressed; + resultIdx = events[i][0]; + } else if (timePressed == maxTime && resultIdx > events[i][0]) { + resultIdx = events[i][0]; + } + prevTime = events[i][1]; + } + return resultIdx; + } +} diff --git a/Easy/Buy Two Chocolates.java b/Easy/Buy Two Chocolates.java new file mode 100644 index 00000000..fac6699e --- /dev/null +++ b/Easy/Buy Two Chocolates.java @@ -0,0 +1,16 @@ +class Solution { + public int buyChoco(int[] prices, int money) { + int cheapestChocolate = Math.min(prices[0], prices[1]); + int secondCheapestChocolate = Math.max(prices[0], prices[1]); + for (int i = 2; i < prices.length; i++) { + if (prices[i] < cheapestChocolate) { + secondCheapestChocolate = cheapestChocolate; + cheapestChocolate = prices[i]; + } else if (prices[i] < secondCheapestChocolate) { + secondCheapestChocolate = prices[i]; + } + } + int totalCost = cheapestChocolate + secondCheapestChocolate; + return totalCost <= money ? (money - totalCost) : money; + } +} diff --git a/Easy/Calculate Amount Paid in Taxes.java b/Easy/Calculate Amount Paid in Taxes.java new file mode 100644 index 00000000..77ae27e2 --- /dev/null +++ b/Easy/Calculate Amount Paid in Taxes.java @@ -0,0 +1,20 @@ +class Solution { + public double calculateTax(int[][] brackets, int income) { + if (income == 0) { + return 0.0; + } + double tax = 0.0; + int idx = 0; + while (idx < brackets.length) { + int[] currentBracket = brackets[idx]; + int amount = idx > 0 ? (Math.min(currentBracket[0], income)) - brackets[idx - 1][0] : Math.min(currentBracket[0], income); + double taxPercentage = ((double) currentBracket[1]) / 100; + tax += taxPercentage * amount; + if (income < currentBracket[0]) { + break; + } + idx++; + } + return tax; + } +} diff --git a/Easy/Calculate Delayed Arrival Time.java b/Easy/Calculate Delayed Arrival Time.java new file mode 100644 index 00000000..47367e00 --- /dev/null +++ b/Easy/Calculate Delayed Arrival Time.java @@ -0,0 +1,6 @@ +class Solution { + public int findDelayedArrivalTime(int arrivalTime, int delayedTime) { + int newTime = arrivalTime + delayedTime; + return newTime - (newTime >= 24 ? 24 : 0); + } +} diff --git a/Easy/Calculate Digit Sum of a String.java b/Easy/Calculate Digit Sum of a String.java new file mode 100644 index 00000000..cf5e9bad --- /dev/null +++ b/Easy/Calculate Digit Sum of a String.java @@ -0,0 +1,20 @@ +class Solution { + public String digitSum(String s, int k) { + while (s.length() > k) { + s = formDigitSum(s, k); + } + return s; + } + + private String formDigitSum(String s, int k) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length(); i += k) { + int currSum = 0; + for (int j = i; j < Math.min(i + k, s.length()); j++) { + currSum += Character.getNumericValue(s.charAt(j)); + } + sb.append(currSum); + } + return sb.toString(); + } +} diff --git a/Easy/Calculate Money in Leetcode Bank.java b/Easy/Calculate Money in Leetcode Bank.java new file mode 100644 index 00000000..0b4a35dc --- /dev/null +++ b/Easy/Calculate Money in Leetcode Bank.java @@ -0,0 +1,21 @@ +class Solution { + public int totalMoney(int n) { + int totalAmount = 0; + int mondayMoney = 1; + while (n > 0) { + totalAmount += mondayMoney++; + n--; + int daysInWeek = Math.min(6, n); + totalAmount += getCummulativeSum(mondayMoney, daysInWeek); + n -= daysInWeek; + } + return totalAmount; + } + + private int getCummulativeSum(int firstTerm, int n) { + if (n <= 0) { + return 0; + } + return ((2 * firstTerm + (n - 1)) * n) / 2; + } +} diff --git a/Easy/Can Make Arithmetic Progression From Sequence.java b/Easy/Can Make Arithmetic Progression From Sequence.java index edc5b0db..fbd09e98 100644 --- a/Easy/Can Make Arithmetic Progression From Sequence.java +++ b/Easy/Can Make Arithmetic Progression From Sequence.java @@ -1,12 +1,12 @@ class Solution { - public boolean canMakeArithmeticProgression(int[] arr) { - Arrays.sort(arr); - int diff = arr[1] - arr[0]; - for (int i = 2; i < arr.length; i++) { - if (arr[i] - arr[i - 1] != diff) { - return false; - } + public boolean canMakeArithmeticProgression(int[] arr) { + Arrays.sort(arr); + int diff = arr[1] - arr[0]; + for (int i = 2; i < arr.length; i++) { + if (arr[i] - arr[i - 1] != diff) { + return false; + } + } + return true; } - return true; - } } diff --git a/Easy/Can Place Flowers.java b/Easy/Can Place Flowers.java index c02aa20b..eb2a21fb 100644 --- a/Easy/Can Place Flowers.java +++ b/Easy/Can Place Flowers.java @@ -1,28 +1,19 @@ class Solution { public boolean canPlaceFlowers(int[] flowerbed, int n) { - for (int i=0;i 1) { - if (flowerbed[i] == 0 && flowerbed[i+1] == 0) { - flowerbed[i] = 1; - n--; - } - } - else if (flowerbed[i] == 0 && flowerbed.length > 2 && flowerbed[i-1] == 0 && i+1 < flowerbed.length && flowerbed[i+1] == 0) { + for (int i = 0; i < flowerbed.length && n > 0; i++) { + if (canPlaceCheck(i, flowerbed)) { flowerbed[i] = 1; n--; - } - else if (i == flowerbed.length-1 && flowerbed.length > 1) { - if (flowerbed[i-1] == 0 && flowerbed[i] == 0) { - flowerbed[i] = 1; - n--; - } - } - else if (flowerbed.length == 1 && flowerbed[0] == 0) { - n--; - } - - if (n <= 0) break; + } } - return n<=0; + return n == 0; + } + + private boolean canPlaceCheck(int i, int[] flowerbed) { + return flowerbed[i] == 0 && ( + (i == 0 && (i + 1 == flowerbed.length || flowerbed[i + 1] == 0)) || + (i == flowerbed.length - 1 && (i - 1 == -1 || flowerbed[i - 1] == 0)) || + (i != 0 && i != flowerbed.length - 1 && flowerbed[i - 1] == 0 && flowerbed[i + 1] == 0) + ); } } diff --git a/Easy/Capitalize the Title.java b/Easy/Capitalize the Title.java new file mode 100644 index 00000000..2481e553 --- /dev/null +++ b/Easy/Capitalize the Title.java @@ -0,0 +1,8 @@ +class Solution { + public String capitalizeTitle(String title) { + return Arrays.stream(title.split("\\s+")) + .map(e -> e.length() <= 2 ? e.toLowerCase() : + e.substring(0, 1).toUpperCase() + e.substring(1).toLowerCase()) + .collect(Collectors.joining(" ")); + } +} diff --git a/Easy/Categorize Box According to Criteria.java b/Easy/Categorize Box According to Criteria.java new file mode 100644 index 00000000..0c817a0a --- /dev/null +++ b/Easy/Categorize Box According to Criteria.java @@ -0,0 +1,23 @@ +class Solution { + + private static final int BULKY_DIMENSION_THRESHOLD = 1000_0; + private static final int BULKY_VOLUME_THRESHOLD = 1000_000_000; + private static final int HEAVY_MASS_THRESHOLD = 100; + + public String categorizeBox(int length, int width, int height, int mass) { + long volume = ((long) length) * width * height; + boolean isBulky = length >= BULKY_DIMENSION_THRESHOLD || + width >= BULKY_DIMENSION_THRESHOLD || + height >= BULKY_DIMENSION_THRESHOLD || + mass >= BULKY_DIMENSION_THRESHOLD || + volume >= BULKY_VOLUME_THRESHOLD; + boolean isHeavy = mass >= HEAVY_MASS_THRESHOLD; + if (isBulky && isHeavy) { + return "Both"; + } + if (!(isBulky || isHeavy)) { + return "Neither"; + } + return isBulky ? "Bulky" : "Heavy"; + } +} diff --git a/Easy/Cells in a Range on an Excel Sheet.java b/Easy/Cells in a Range on an Excel Sheet.java new file mode 100644 index 00000000..8307c2b5 --- /dev/null +++ b/Easy/Cells in a Range on an Excel Sheet.java @@ -0,0 +1,16 @@ +class Solution { + public List cellsInRange(String s) { + List cells = new ArrayList<>(); + String[] splits = s.split(":"); + char startCol = splits[0].charAt(0); + int startRow = Character.getNumericValue(splits[0].charAt(1)); + char endCol = splits[1].charAt(0); + int endRow = Character.getNumericValue(splits[1].charAt(1)); + for (char c = startCol; c <= endCol; c = (char) (c + 1)) { + for (int j = startRow; j <= endRow; j++) { + cells.add(c + "" + j); + } + } + return cells; + } +} diff --git a/Easy/Check Array Formation Through Concatenation.java b/Easy/Check Array Formation Through Concatenation.java new file mode 100644 index 00000000..c3fb461d --- /dev/null +++ b/Easy/Check Array Formation Through Concatenation.java @@ -0,0 +1,17 @@ +class Solution { + public boolean canFormArray(int[] arr, int[][] pieces) { + Map indexMap = new HashMap<>(); + for (int idx = 0; idx < arr.length; idx++) { + indexMap.put(arr[idx], idx); + } + for (int[] piece : pieces) { + for (int idx = 0; idx < piece.length; idx++) { + if (!indexMap.containsKey(piece[idx]) || + idx > 0 && indexMap.getOrDefault(piece[idx], -1) < indexMap.getOrDefault(piece[idx - 1], -1)) { + return false; + } + } + } + return true; + } +} diff --git a/Easy/Check Distances Between Same Letters.java b/Easy/Check Distances Between Same Letters.java new file mode 100644 index 00000000..ed5367f6 --- /dev/null +++ b/Easy/Check Distances Between Same Letters.java @@ -0,0 +1,16 @@ +class Solution { + public boolean checkDistances(String s, int[] distance) { + Map charToIdx = new HashMap<>(); + for (int i = 0; i < s.length(); i++) { + if (charToIdx.containsKey(s.charAt(i))) { + int diff = i - charToIdx.get(s.charAt(i)) - 1; + if (diff != distance[s.charAt(i) - 'a']) { + return false; + } + } else { + charToIdx.put(s.charAt(i), i); + } + } + return true; + } +} diff --git a/Easy/Check If It Is a Straight Line.java b/Easy/Check If It Is a Straight Line.java index 18798145..407ed220 100644 --- a/Easy/Check If It Is a Straight Line.java +++ b/Easy/Check If It Is a Straight Line.java @@ -1,24 +1,21 @@ -class Solution { - public boolean checkStraightLine(int[][] coordinates) { - if (coordinates.length <= 2) { - return true; +class Solution { + public boolean checkStraightLine(int[][] coordinates) { + int deltaY = getYDiff(coordinates[1], coordinates[0]); + int deltaX = getXDiff(coordinates[1], coordinates[0]); + for (int i = 2; i < coordinates.length; i++) { + if (deltaY * getXDiff(coordinates[i], coordinates[0]) != deltaX * getYDiff(coordinates[i], coordinates[0])) { + return false; + } + } + return true; } - int[] p1 = coordinates[0]; - int[] p2 = coordinates[1]; - for (int i = 2; i < coordinates.length; i++) { - if (!isCollinear(coordinates[i], p1, p2)) { - return false; - } + + private int getYDiff(int[] a, int[] b) { + return a[1] - b[1]; } - return true; - } - - private boolean isCollinear(int[] c, int[] p1, int[] p2) { - if (p1[0] == c[0] || p2[0] == c[0]) { - return false; + + private int getXDiff(int[] a, int[] b) { + return a[0] - b[0]; } - int slope1 = (p1[1] - c[1]) / (p1[0] - c[0]); - int slope2 = (p2[1] - c[1]) / (p2[0] - c[0]); - return slope1 == slope2; - } + } diff --git a/Easy/Check If String Is a Prefix of Array.java b/Easy/Check If String Is a Prefix of Array.java new file mode 100644 index 00000000..faf8f894 --- /dev/null +++ b/Easy/Check If String Is a Prefix of Array.java @@ -0,0 +1,17 @@ +class Solution { + public boolean isPrefixString(String s, String[] words) { + int idx = 0; + for (String word : words) { + for (int i = 0; i < word.length(); i++) { + if (word.charAt(i) != s.charAt(idx)) { + return false; + } + idx++; + if (idx == s.length()) { + return i == word.length() - 1; + } + } + } + return idx == s.length(); + } +} diff --git a/Easy/Check If Two String Arrays are Equivalent.java b/Easy/Check If Two String Arrays are Equivalent.java new file mode 100644 index 00000000..880301c2 --- /dev/null +++ b/Easy/Check If Two String Arrays are Equivalent.java @@ -0,0 +1,24 @@ +class Solution { + public boolean arrayStringsAreEqual(String[] word1, String[] word2) { + int idxOne = 0; + int idxTwo = 0; + int wordIdxOne = 0; + int wordIdxTwo = 0; + while (idxOne < word1.length && idxTwo < word2.length) { + if (word1[idxOne].charAt(wordIdxOne) != word2[idxTwo].charAt(wordIdxTwo)) { + return false; + } + wordIdxOne++; + wordIdxTwo++; + if (wordIdxOne == word1[idxOne].length()) { + wordIdxOne = 0; + idxOne++; + } + if (wordIdxTwo == word2[idxTwo].length()) { + wordIdxTwo = 0; + idxTwo++; + } + } + return idxOne == word1.length && idxTwo == word2.length; + } +} diff --git a/Easy/Check If a Number Is Majority Element in a Sorted Array.java b/Easy/Check If a Number Is Majority Element in a Sorted Array.java index a5620749..6491d715 100644 --- a/Easy/Check If a Number Is Majority Element in a Sorted Array.java +++ b/Easy/Check If a Number Is Majority Element in a Sorted Array.java @@ -1,13 +1,38 @@ class Solution { + + private static enum Direction { + LEFT, RIGHT; + } + public boolean isMajorityElement(int[] nums, int target) { - if (nums.length == 1) { - return nums[0] == target; + int firstIndex = findIndex(nums, target, Direction.LEFT); + if (firstIndex == -1) { + return false; } - - if (nums.length == 2) { - return nums[0] == target && nums[1] == target; + int lastIndex = findIndex(nums, target, Direction.RIGHT); + int occurrences = lastIndex - firstIndex + 1; + return occurrences > nums.length / 2; + } + + private int findIndex(int[] nums, int target, Direction direction) { + int idx = -1; + int start = 0; + int end = nums.length - 1; + while (start <= end) { + int mid = (start + end) / 2; + if (nums[mid] == target) { + idx = mid; + if (direction == Direction.LEFT) { + end = mid - 1; + } else { + start = mid + 1; + } + } else if (nums[mid] > target) { + end = mid - 1; + } else { + start = mid + 1; + } } - - return nums[nums.length / 2 - 1] == target && nums[nums.length / 2 + 1] == target; + return idx; } } diff --git a/Easy/Check Whether Two Strings are Almost Equivalent.java b/Easy/Check Whether Two Strings are Almost Equivalent.java new file mode 100644 index 00000000..e80ee212 --- /dev/null +++ b/Easy/Check Whether Two Strings are Almost Equivalent.java @@ -0,0 +1,15 @@ +class Solution { + public boolean checkAlmostEquivalent(String word1, String word2) { + int[] frequency = new int[26]; + for (int i = 0; i < word1.length(); i++) { + frequency[word1.charAt(i) - 'a']++; + frequency[word2.charAt(i) - 'a']--; + } + for (int i = 0; i < 26; i++) { + if (Math.abs(frequency[i]) > 3) { + return false; + } + } + return true; + } +} diff --git a/Easy/Check if All A's Appears Before All B's.java b/Easy/Check if All A's Appears Before All B's.java new file mode 100644 index 00000000..aab35c42 --- /dev/null +++ b/Easy/Check if All A's Appears Before All B's.java @@ -0,0 +1,17 @@ +class Solution { + public boolean checkString(String s) { + boolean aFound = false; + boolean bFound = false; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == 'a') { + if (bFound) { + return false; + } + aFound = true; + } else { + bFound = true; + } + } + return true; + } +} diff --git a/Easy/Check if All Characters Have Equal Number of Occurrences.java b/Easy/Check if All Characters Have Equal Number of Occurrences.java new file mode 100644 index 00000000..1de5d301 --- /dev/null +++ b/Easy/Check if All Characters Have Equal Number of Occurrences.java @@ -0,0 +1,7 @@ +class Solution { + public boolean areOccurrencesEqual(String s) { + return new HashSet<>(s.chars().mapToObj(c -> (char) c) + .collect(Collectors.groupingBy(Function.identity(), HashMap::new, Collectors.counting())) + .values()).size() == 1; + } +} diff --git a/Easy/Check if All the Integers in a Range Are Covered.java b/Easy/Check if All the Integers in a Range Are Covered.java new file mode 100644 index 00000000..63a5fd2d --- /dev/null +++ b/Easy/Check if All the Integers in a Range Are Covered.java @@ -0,0 +1,14 @@ +class Solution { + public boolean isCovered(int[][] ranges, int left, int right) { + Arrays.sort(ranges, Comparator.comparingInt((int[] o) -> o[0])); + for (int[] range : ranges) { + if (left >= range[0] && left <= range[1]) { + left = range[1] + 1; + } + if (left > right) { + return true; + } + } + return false; + } +} diff --git a/Easy/Check if Array Is Sorted and Rotated.java b/Easy/Check if Array Is Sorted and Rotated.java new file mode 100644 index 00000000..6ecc109d --- /dev/null +++ b/Easy/Check if Array Is Sorted and Rotated.java @@ -0,0 +1,14 @@ +class Solution { + public boolean check(int[] nums) { + boolean rotated = false; + for (int i = 0; i < nums.length - 1; i++) { + if (nums[i] > nums[i + 1]) { + if (rotated) { + return false; + } + rotated = true; + } + } + return !rotated || nums[nums.length - 1] <= nums[0]; + } +} diff --git a/Easy/Check if Array is Good.java b/Easy/Check if Array is Good.java new file mode 100644 index 00000000..f0b86ddc --- /dev/null +++ b/Easy/Check if Array is Good.java @@ -0,0 +1,24 @@ +class Solution { + public boolean isGood(int[] nums) { + if (nums.length <= 1) { + return false; + } + int n = nums.length - 1; + Map map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + for (int i = 1; i <= n; i++) { + if (!map.containsKey(i)) { + return false; + } + if (map.get(i) > 1 && i != n) { + return false; + } + if (i == n && map.get(i) != 2) { + return false; + } + } + return true; + } +} diff --git a/Easy/Check if Binary String Has at Most One Segment of Ones.java b/Easy/Check if Binary String Has at Most One Segment of Ones.java new file mode 100644 index 00000000..5c9f9f51 --- /dev/null +++ b/Easy/Check if Binary String Has at Most One Segment of Ones.java @@ -0,0 +1,23 @@ +class Solution { + public boolean checkOnesSegment(String s) { + boolean foundContiguousSegment = false; + int idx = 0; + int n = s.length(); + while (idx < n) { + int count = 0; + while (idx < n && s.charAt(idx) == '1') { + count++; + idx++; + } + if (count >= 1) { + if (foundContiguousSegment) { + return false; + } + foundContiguousSegment = true; + } else { + idx++; + } + } + return foundContiguousSegment; + } +} diff --git a/Easy/Check if Bitwise OR Has Trailing Zeros.java b/Easy/Check if Bitwise OR Has Trailing Zeros.java new file mode 100644 index 00000000..b1aedc22 --- /dev/null +++ b/Easy/Check if Bitwise OR Has Trailing Zeros.java @@ -0,0 +1,7 @@ +class Solution { + public boolean hasTrailingZeros(int[] nums) { + return Arrays.stream(nums) + .filter(num -> Integer.numberOfTrailingZeros(num) > 0) + .count() >= 2; + } +} diff --git a/Easy/Check if Every Row and Column Contains All Numbers.java b/Easy/Check if Every Row and Column Contains All Numbers.java new file mode 100644 index 00000000..f64e1cfc --- /dev/null +++ b/Easy/Check if Every Row and Column Contains All Numbers.java @@ -0,0 +1,14 @@ +class Solution { + public boolean checkValid(int[][] matrix) { + Map> rowMap = new HashMap<>(); + Map> colMap = new HashMap<>(); + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[0].length; j++) { + rowMap.computeIfAbsent(i, k -> new HashSet<>()).add(matrix[i][j]); + colMap.computeIfAbsent(j, k -> new HashSet<>()).add(matrix[i][j]); + } + } + return rowMap.values().stream().allMatch(e -> e.size() == matrix.length) && + colMap.values().stream().allMatch(e -> e.size() == matrix.length); + } +} diff --git a/Easy/Check if Grid Satisfies Conditions.java b/Easy/Check if Grid Satisfies Conditions.java new file mode 100644 index 00000000..93891460 --- /dev/null +++ b/Easy/Check if Grid Satisfies Conditions.java @@ -0,0 +1,17 @@ +class Solution { + public boolean satisfiesConditions(int[][] grid) { + int rows = grid.length; + int cols = grid[0].length; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (i + 1 < rows && grid[i][j] != grid[i + 1][j]) { + return false; + } + if (j + 1 < cols && grid[i][j] == grid[i][j + 1]) { + return false; + } + } + } + return true; + } +} diff --git a/Easy/Check if Matrix Is X-Matrix.java b/Easy/Check if Matrix Is X-Matrix.java new file mode 100644 index 00000000..34bc31af --- /dev/null +++ b/Easy/Check if Matrix Is X-Matrix.java @@ -0,0 +1,19 @@ +class Solution { + public boolean checkXMatrix(int[][] grid) { + int n = grid.length; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (i == j || i + j == n - 1) { + if (grid[i][j] == 0) { + return false; + } + } else { + if (grid[i][j] != 0) { + return false; + } + } + } + } + return true; + } +} diff --git a/Easy/Check if Number Has Equal Digit Count and Digit Value.java b/Easy/Check if Number Has Equal Digit Count and Digit Value.java new file mode 100644 index 00000000..8ea9bbc7 --- /dev/null +++ b/Easy/Check if Number Has Equal Digit Count and Digit Value.java @@ -0,0 +1,16 @@ +class Solution { + public boolean digitCount(String num) { + int[] frequency = new int[10]; + for (char c : num.toCharArray()) { + frequency[Character.getNumericValue(c)]++; + } + for (int i = 0; i < num.length(); i++) { + int digit = i; + int expectedFrequency = Character.getNumericValue(num.charAt(i)); + if (frequency[digit] != expectedFrequency) { + return false; + } + } + return true; + } +} diff --git a/Easy/Check if Numbers Are Ascending in a Sentence.java b/Easy/Check if Numbers Are Ascending in a Sentence.java new file mode 100644 index 00000000..b7f5ac65 --- /dev/null +++ b/Easy/Check if Numbers Are Ascending in a Sentence.java @@ -0,0 +1,19 @@ +class Solution { + public boolean areNumbersAscending(String s) { + int prevValue = Integer.MIN_VALUE; + for (int i = 0; i < s.length(); ) { + if (Character.isDigit(s.charAt(i))) { + int currNum = 0; + while (i < s.length() && Character.isDigit(s.charAt(i))) { + currNum = currNum * 10 + Character.getNumericValue(s.charAt(i++)); + } + if (currNum <= prevValue) { + return false; + } + prevValue = currNum; + } + i++; + } + return true; + } +} diff --git a/Easy/Check if One String Swap Can Make Strings Equal.java b/Easy/Check if One String Swap Can Make Strings Equal.java new file mode 100644 index 00000000..fca6fc9d --- /dev/null +++ b/Easy/Check if One String Swap Can Make Strings Equal.java @@ -0,0 +1,21 @@ +class Solution { + public boolean areAlmostEqual(String s1, String s2) { + int swapIdx = -1; + boolean swapped = false; + for (int i = 0; i < s1.length(); i++) { + if (s1.charAt(i) != s2.charAt(i)) { + if (swapped) { + return false; + } + if (swapIdx != -1) { + if (!(s1.charAt(swapIdx) == s2.charAt(i) && s1.charAt(i) == s2.charAt(swapIdx))) { + return false; + } + swapped = true; + } + swapIdx = i; + } + } + return swapIdx == -1 || (swapIdx != -1 && swapped); + } +} diff --git a/Easy/Check if String Is Decomposable Into Value-Equal Substrings.java b/Easy/Check if String Is Decomposable Into Value-Equal Substrings.java new file mode 100644 index 00000000..6d6d55c4 --- /dev/null +++ b/Easy/Check if String Is Decomposable Into Value-Equal Substrings.java @@ -0,0 +1,25 @@ +class Solution { + public boolean isDecomposable(String s) { + boolean sizeTwoFound = false; + int idx = 0; + while (idx < s.length()) { + char c = s.charAt(idx); + int tempIdx = idx; + while (tempIdx < s.length() && s.charAt(tempIdx) == c && tempIdx - idx < 3) { + tempIdx++; + } + int occurrences = tempIdx - idx; + if (occurrences < 2) { + return false; + } + if (occurrences == 2) { + if (sizeTwoFound) { + return false; + } + sizeTwoFound = true; + } + idx = tempIdx; + } + return sizeTwoFound; + } +} diff --git a/Easy/Check if Strings Can be Made Equal With Operations I.java b/Easy/Check if Strings Can be Made Equal With Operations I.java new file mode 100644 index 00000000..cc99065a --- /dev/null +++ b/Easy/Check if Strings Can be Made Equal With Operations I.java @@ -0,0 +1,9 @@ +class Solution { + public boolean canBeEqual(String s1, String s2) { + boolean firstSwap = (s1.charAt(0) == s2.charAt(0) && s1.charAt(2) == s2.charAt(2)) || + (s1.charAt(2) == s2.charAt(0) && s1.charAt(0) == s2.charAt(2)); + boolean secondSwap = (s1.charAt(1) == s2.charAt(1) && s1.charAt(3) == s2.charAt(3)) || + (s1.charAt(1) == s2.charAt(3) && s1.charAt(3) == s2.charAt(1)); + return firstSwap && secondSwap; + } +} diff --git a/Easy/Check if The Number is Fascinating.java b/Easy/Check if The Number is Fascinating.java new file mode 100644 index 00000000..d5074568 --- /dev/null +++ b/Easy/Check if The Number is Fascinating.java @@ -0,0 +1,13 @@ +class Solution { + public boolean isFascinating(int n) { + return isFascinatingHelper(n + "" + 2 * n + "" + 3 * n); + } + + private boolean isFascinatingHelper(String s) { + return s.length() == 9 && s.chars() + .mapToObj(c -> (char) c) + .filter(c -> c != '0') + .collect(Collectors.toSet()) + .size() == 9; + } +} diff --git a/Easy/Check if Word Equals Summation of Two Words.java b/Easy/Check if Word Equals Summation of Two Words.java new file mode 100644 index 00000000..d7aa68ce --- /dev/null +++ b/Easy/Check if Word Equals Summation of Two Words.java @@ -0,0 +1,13 @@ +class Solution { + public boolean isSumEqual(String firstWord, String secondWord, String targetWord) { + return getNumericalValue(firstWord) + getNumericalValue(secondWord) == getNumericalValue(targetWord); + } + + private int getNumericalValue(String s) { + int value = 0; + for (char c : s.toCharArray()) { + value = value * 10 + (c - 'a'); + } + return value; + } +} diff --git a/Easy/Check if a String Is an Acronym of Words.java b/Easy/Check if a String Is an Acronym of Words.java new file mode 100644 index 00000000..5608783c --- /dev/null +++ b/Easy/Check if a String Is an Acronym of Words.java @@ -0,0 +1,9 @@ +class Solution { + public boolean isAcronym(List words, String s) { + StringBuilder sb = new StringBuilder(); + for (String word : words) { + sb.append(word.charAt(0)); + } + return sb.toString().equals(s); + } +} diff --git a/Easy/Check if an Array Is Consecutive.java b/Easy/Check if an Array Is Consecutive.java new file mode 100644 index 00000000..618d43e6 --- /dev/null +++ b/Easy/Check if an Array Is Consecutive.java @@ -0,0 +1,15 @@ +class Solution { + public boolean isConsecutive(int[] nums) { + int min = Integer.MAX_VALUE; + for (int num : nums) { + min = Math.min(num, min); + } + Set set = new HashSet<>(); + for (int num : nums) { + if (num - min >= nums.length || !set.add(num - min)) { + return false; + } + } + return true; + } +} diff --git a/Easy/Check if the Sentence Is Pangram.java b/Easy/Check if the Sentence Is Pangram.java new file mode 100644 index 00000000..a7d7b8e8 --- /dev/null +++ b/Easy/Check if the Sentence Is Pangram.java @@ -0,0 +1,5 @@ +class Solution { + public boolean checkIfPangram(String sentence) { + return sentence.chars().mapToObj(c -> (char) c).collect(Collectors.toSet()).size() == 26; + } +} diff --git a/Easy/Circular Sentence.java b/Easy/Circular Sentence.java new file mode 100644 index 00000000..51b21134 --- /dev/null +++ b/Easy/Circular Sentence.java @@ -0,0 +1,16 @@ +class Solution { + public boolean isCircularSentence(String sentence) { + String[] words = sentence.split("\\s+"); + int n = words.length; + for (int i = 0; i < n - 1; i++) { + char lastCharOfCurrentWord = words[i].charAt(words[i].length() - 1); + char firstCharOfNextWord = words[i + 1].charAt(0); + if (lastCharOfCurrentWord != firstCharOfNextWord) { + return false; + } + } + char lastCharOfLastWord = words[n - 1].charAt(words[n - 1].length() - 1); + char firstCharOfFirstWord = words[0].charAt(0); + return lastCharOfLastWord == firstCharOfFirstWord; + } +} diff --git a/Easy/Clear Digits.java b/Easy/Clear Digits.java new file mode 100644 index 00000000..1d308863 --- /dev/null +++ b/Easy/Clear Digits.java @@ -0,0 +1,15 @@ +class Solution { + public String clearDigits(String s) { + StringBuilder sb = new StringBuilder(); + for (char c : s.toCharArray()) { + if (Character.isDigit(c)) { + if (!sb.isEmpty()) { + sb.deleteCharAt(sb.length() - 1); + } + } else { + sb.append(c); + } + } + return sb.toString(); + } +} diff --git a/Easy/Climbing Stairs.java b/Easy/Climbing Stairs.java index e35175f2..ad49acda 100644 --- a/Easy/Climbing Stairs.java +++ b/Easy/Climbing Stairs.java @@ -1,20 +1,19 @@ class Solution { - int[] memo; - public int climbStairs(int n) { - if (n == 1) { - return 1; + public int climbStairs(int n) { + Integer[] dp = new Integer[n + 1]; + return climbStairs(dp, n); } - memo = new int[n + 1]; - memo[1] = 1; - memo[2] = 2; - return helper(n); - } - - private int helper(int n) { - if (memo[n] != 0) { - return memo[n]; + + private int climbStairs(Integer[] dp, int n) { + if (n == 1) { + return 1; + } + if (n == 2) { + return 2; + } + if (dp[n] != null) { + return dp[n]; + } + return dp[n] = climbStairs(dp, n - 1) + climbStairs(dp, n - 2); } - memo[n] = helper(n - 1) + helper(n - 2); - return memo[n]; - } } diff --git a/Easy/Closest Binary Search Tree Value.java b/Easy/Closest Binary Search Tree Value.java index 0f1ad50c..cbf397e0 100644 --- a/Easy/Closest Binary Search Tree Value.java +++ b/Easy/Closest Binary Search Tree Value.java @@ -4,30 +4,35 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { public int closestValue(TreeNode root, double target) { - int[] ans = {0}; - double minDiff = Double.MAX_VALUE; - helper(root, target, ans, minDiff); - return ans[0]; - } + double[] result = {Double.MAX_VALUE, -1}; + helper(root, target, result); + return (int) result[1]; + } - private void helper(TreeNode root, double target, int[] ans, double minDiff) { + private void helper(TreeNode root, double target, double[] result) { if (root == null) { return; } - if (Math.abs(root.val - target) < minDiff) { - minDiff = Math.abs(root.val - target); - ans[0] = root.val; - } - if (root.val < target) { - helper(root.right, target, ans, minDiff); + double diff = Math.abs(root.val - target); + if (diff <= result[0]) { + result[0] = diff; + result[1] = root.val; } - else { - helper(root.left, target, ans, minDiff); + if (root.val > target) { + helper(root.left, target, result); + } else { + helper(root.right, target, result); } } } diff --git a/Easy/Concatenation of Array.java b/Easy/Concatenation of Array.java new file mode 100644 index 00000000..f4042c0b --- /dev/null +++ b/Easy/Concatenation of Array.java @@ -0,0 +1,9 @@ +class Solution { + public int[] getConcatenation(int[] nums) { + int[] ans = new int[nums.length * 2]; + for (int i = 0; i < nums.length; i++) { + ans[i + nums.length] = ans[i] = nums[i]; + } + return ans; + } +} diff --git a/Easy/Consecutive Characters.java b/Easy/Consecutive Characters.java index cb37c58b..594b38c9 100644 --- a/Easy/Consecutive Characters.java +++ b/Easy/Consecutive Characters.java @@ -1,17 +1,14 @@ class Solution { public int maxPower(String s) { - int count = 0; - int idx = 0; - int n = s.length(); - while (idx < n) { - char c = s.charAt(idx); - int tempCount = 0; - while (idx < n && s.charAt(idx) == c) { + int maximumRepeatingCount = 0; + for (int idx = 0; idx < s.length();) { + char currentChar = s.charAt(idx); + int currIdx = idx; + while (idx < s.length() && s.charAt(idx) == currentChar) { idx++; - tempCount++; } - count = Math.max(count, tempCount); + maximumRepeatingCount = Math.max(maximumRepeatingCount, idx - currIdx); } - return count; + return maximumRepeatingCount; } } diff --git a/Easy/Construct String from Binary Tree.java b/Easy/Construct String from Binary Tree.java index be38ff5e..a6b1a205 100644 --- a/Easy/Construct String from Binary Tree.java +++ b/Easy/Construct String from Binary Tree.java @@ -14,26 +14,26 @@ * } */ class Solution { - public String tree2str(TreeNode t) { + public String tree2str(TreeNode root) { StringBuilder sb = new StringBuilder(); - helper(t, sb); + helper(root, sb); return sb.toString(); } - private void helper(TreeNode node, StringBuilder sb) { - if (node == null) { + private void helper(TreeNode root, StringBuilder sb) { + if (root == null) { return; } - sb.append(node.val); - if (node.left == null && node.right == null) { + sb.append(root.val); + if (root.left == null && root.right == null) { return; } sb.append("("); - helper(node.left, sb); + helper(root.left, sb); sb.append(")"); - if (node.right != null) { + if (root.right != null) { sb.append("("); - helper(node.right, sb); + helper(root.right, sb); sb.append(")"); } } diff --git a/Easy/Contains Duplicate II.java b/Easy/Contains Duplicate II.java index 579e6ae4..1200875f 100644 --- a/Easy/Contains Duplicate II.java +++ b/Easy/Contains Duplicate II.java @@ -1,14 +1,12 @@ class Solution { - public boolean containsNearbyDuplicate(int[] nums, int k) { - Map map = new HashMap<>(); - for (int i=0;i map = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + if (map.containsKey(nums[i]) && Math.abs(map.get(nums[i]) - i) <= k) { + return true; + } + map.put(nums[i], i); } + return false; + } } diff --git a/Easy/Contains Duplicate.java b/Easy/Contains Duplicate.java new file mode 100644 index 00000000..156ad8f9 --- /dev/null +++ b/Easy/Contains Duplicate.java @@ -0,0 +1,5 @@ +class Solution { + public boolean containsDuplicate(int[] nums) { + return Arrays.stream(nums).boxed().collect(Collectors.toSet()).size() < nums.length; + } +} diff --git a/Easy/Convert 1D Array Into 2D Array.java b/Easy/Convert 1D Array Into 2D Array.java new file mode 100644 index 00000000..80b7323e --- /dev/null +++ b/Easy/Convert 1D Array Into 2D Array.java @@ -0,0 +1,17 @@ +class Solution { + public int[][] construct2DArray(int[] original, int m, int n) { + if (m * n != original.length) { + return new int[][]{}; + } + int[][] arr = new int[m][n]; + int idx = 0; + int arrIdx = 0; + while (idx < original.length) { + for (int i = 0; i < n; i++) { + arr[arrIdx][i] = original[idx++]; + } + arrIdx++; + } + return arr; + } +} diff --git a/Easy/Convert BST to Greater Tree.java b/Easy/Convert BST to Greater Tree.java new file mode 100644 index 00000000..8a0ff782 --- /dev/null +++ b/Easy/Convert BST to Greater Tree.java @@ -0,0 +1,36 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public TreeNode convertBST(TreeNode root) { + Stack stack = new Stack<>(); + addToStack(stack, root); + int currSum = 0; + while (!stack.isEmpty()) { + TreeNode removed = stack.pop(); + currSum += removed.val; + removed.val = currSum; + addToStack(stack, removed.left); + } + return root; + } + + private void addToStack(Stack stack, TreeNode node) { + while (node != null) { + stack.push(node); + node = node.right; + } + } +} diff --git a/Easy/Convert BST to greater tree.java b/Easy/Convert BST to greater tree.java deleted file mode 100644 index f4b736f3..00000000 --- a/Easy/Convert BST to greater tree.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - int updatedVal = 0; - public TreeNode convertBST(TreeNode root) { - helper(root); - return root; - } - - private void helper(TreeNode root) { - if (root == null) { - return; - } - helper(root.right); - updatedVal += root.val; - root.val = updatedVal; - helper(root.left); - } -} diff --git a/Easy/Convert Binary Number in a Linked List to Integer.java b/Easy/Convert Binary Number in a Linked List to Integer.java index 22ed597d..88ac4468 100644 --- a/Easy/Convert Binary Number in a Linked List to Integer.java +++ b/Easy/Convert Binary Number in a Linked List to Integer.java @@ -3,27 +3,25 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public int getDecimalValue(ListNode head) { - int length = getLength(head); - int sum = 0; - while (head != null) { - sum += ((int) Math.pow(2, length - 1)) * head.val; - length--; - head = head.next; + int nodeLength = -1; + ListNode curr = head; + while (curr != null) { + nodeLength++; + curr = curr.next; } - return sum; - } - - private int getLength(ListNode head) { - int count = 0; - while (head != null) { - count++; - head = head.next; + int decimalValue = 0; + curr = head; + while (curr != null) { + decimalValue += curr.val * Math.pow(2, nodeLength--); + curr = curr.next; } - return count; + return decimalValue; } } diff --git a/Easy/Convert Sorted Array To Binary Search Tree.java b/Easy/Convert Sorted Array To Binary Search Tree.java index 55cbd37e..19d14059 100644 --- a/Easy/Convert Sorted Array To Binary Search Tree.java +++ b/Easy/Convert Sorted Array To Binary Search Tree.java @@ -4,24 +4,28 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { public TreeNode sortedArrayToBST(int[] nums) { - int left = 0; - int right = nums.length - 1; - return helper(nums, left, right); + return helper(nums, 0, nums.length - 1); } - private TreeNode helper(int[] nums, int left, int right) { - if (left > right) { + private TreeNode helper(int[] nums, int start, int end) { + if (start > end) { return null; } - int mid = (left + right) / 2; + int mid = (start + end) / 2; TreeNode root = new TreeNode(nums[mid]); - root.left = helper(nums, left, mid - 1); - root.right = helper(nums, mid + 1, right); + root.left = helper(nums, start, mid - 1); + root.right = helper(nums, mid + 1, end); return root; } } diff --git a/Easy/Convert the Temperature.java b/Easy/Convert the Temperature.java new file mode 100644 index 00000000..0b1f250c --- /dev/null +++ b/Easy/Convert the Temperature.java @@ -0,0 +1,5 @@ +class Solution { + public double[] convertTemperature(double celsius) { + return new double[]{/* kelvin= */celsius + 273.15, /* fahrenheit= */celsius * 1.80 + 32.00}; + } +} diff --git a/Easy/Correct a Binary Tree.java b/Easy/Correct a Binary Tree.java new file mode 100644 index 00000000..3ec5f055 --- /dev/null +++ b/Easy/Correct a Binary Tree.java @@ -0,0 +1,48 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public TreeNode correctBinaryTree(TreeNode root) { + Queue queue = new LinkedList<>(); + queue.add(new Pair(root, null)); + while (!queue.isEmpty()) { + int size = queue.size(); + Set visited = new HashSet<>(); + for (int i = 0; i < size; i++) { + Pair pair = queue.remove(); + TreeNode node = pair.node(); + TreeNode parent = pair.parent(); + if (visited.contains(node.right)) { + if (parent.left == node) { + parent.left = null; + } else { + parent.right = null; + } + return root; + } + visited.add(node); + if (node.right != null) { + queue.add(new Pair(node.right, node)); + } + if (node.left != null) { + queue.add(new Pair(node.left, node)); + } + } + } + return root; + } + + private static record Pair(TreeNode node, TreeNode parent) {} +} diff --git a/Easy/Count Asterisks.java b/Easy/Count Asterisks.java new file mode 100644 index 00000000..14a53656 --- /dev/null +++ b/Easy/Count Asterisks.java @@ -0,0 +1,16 @@ +class Solution { + public int countAsterisks(String s) { + int asteriskCount = 0; + int barCount = 0; + for (char c : s.toCharArray()) { + if (c == '|') { + barCount++; + } else if (c == '*') { + if (barCount % 2 == 0) { + asteriskCount++; + } + } + } + return asteriskCount; + } +} diff --git a/Easy/Count Binary Substrings.java b/Easy/Count Binary Substrings.java index fec040fe..a0818c9f 100644 --- a/Easy/Count Binary Substrings.java +++ b/Easy/Count Binary Substrings.java @@ -1,17 +1,19 @@ class Solution { - public int countBinarySubstrings(String s) { - int prev = 0; - int curr = 1; - int res = 0; - - for (int i=1;i= curr) res++; - } - return res; + public int countBinarySubstrings(String s) { + int totalCount = 0; + int currCount = 0; + int oppositeCount = 0; + char currChar = s.charAt(0); + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == currChar) { + currCount++; + } else { + totalCount += Math.min(currCount, oppositeCount); + oppositeCount = currCount; + currCount = 1; + currChar = s.charAt(i); + } } + return totalCount + Math.min(currCount, oppositeCount); + } } diff --git a/Easy/Count Common Words With One Occurrence.java b/Easy/Count Common Words With One Occurrence.java new file mode 100644 index 00000000..514a87bc --- /dev/null +++ b/Easy/Count Common Words With One Occurrence.java @@ -0,0 +1,16 @@ +class Solution { + public int countWords(String[] words1, String[] words2) { + Map map = new HashMap<>(); + buildFrequencyMap(words1, map, 0); + buildFrequencyMap(words2, map, 1); + return (int) map.entrySet().stream() + .filter(entry -> entry.getValue()[0] == 1 && entry.getValue()[1] == 1) + .count(); + } + + private void buildFrequencyMap(String[] words, Map map, int idx) { + for (String word : words) { + map.computeIfAbsent(word, k -> new int[2])[idx]++; + } + } +} diff --git a/Easy/Count Distinct Numbers on Board.java b/Easy/Count Distinct Numbers on Board.java new file mode 100644 index 00000000..42a7ad68 --- /dev/null +++ b/Easy/Count Distinct Numbers on Board.java @@ -0,0 +1,5 @@ +class Solution { + public int distinctIntegers(int n) { + return Math.max(n - 1, 1); + } +} diff --git a/Easy/Count Elements With Maximum Frequency.java b/Easy/Count Elements With Maximum Frequency.java new file mode 100644 index 00000000..0f023200 --- /dev/null +++ b/Easy/Count Elements With Maximum Frequency.java @@ -0,0 +1,17 @@ +class Solution { + public int maxFrequencyElements(int[] nums) { + Map map = new HashMap<>(); + int maxFrequency = 0; + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + maxFrequency = Math.max(maxFrequency, map.get(num)); + } + int count = 0; + for (int num : nums) { + if (map.get(num) == maxFrequency) { + count++; + } + } + return count; + } +} diff --git a/Easy/Count Elements With Strictly Smaller and Greater Elements.java b/Easy/Count Elements With Strictly Smaller and Greater Elements.java new file mode 100644 index 00000000..42b3f09d --- /dev/null +++ b/Easy/Count Elements With Strictly Smaller and Greater Elements.java @@ -0,0 +1,17 @@ +class Solution { + public int countElements(int[] nums) { + int minValue = nums[0]; + int maxValue = nums[0]; + for (int num : nums) { + minValue = Math.min(minValue, num); + maxValue = Math.max(maxValue, num); + } + int count = 0; + for (int num : nums) { + if (num > minValue && num < maxValue) { + count++; + } + } + return count; + } +} diff --git a/Easy/Count Equal and Divisible Pairs in an Array.java b/Easy/Count Equal and Divisible Pairs in an Array.java new file mode 100644 index 00000000..309c090a --- /dev/null +++ b/Easy/Count Equal and Divisible Pairs in an Array.java @@ -0,0 +1,19 @@ +class Solution { + public int countPairs(int[] nums, int k) { + Map> map = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + map.computeIfAbsent(nums[i], j -> new ArrayList<>()).add(i); + } + int numOfPairs = 0; + for (List indices : map.values()) { + for (int i = 0; i < indices.size(); i++) { + for (int j = 0; j < i; j++) { + if (indices.get(i) * indices.get(j) % k == 0) { + numOfPairs++; + } + } + } + } + return numOfPairs; + } +} diff --git a/Easy/Count Hills and Valleys in an Array.java b/Easy/Count Hills and Valleys in an Array.java new file mode 100644 index 00000000..40372dfd --- /dev/null +++ b/Easy/Count Hills and Valleys in an Array.java @@ -0,0 +1,13 @@ +class Solution { + public int countHillValley(int[] nums) { + int count = 0; + int left = nums[0]; + for (int i = 1; i < nums.length - 1; i++) { + if ((left < nums[i] && nums[i] > nums[i + 1]) || (left > nums[i] && nums[i] < nums[i + 1])) { + left = nums[i]; + count++; + } + } + return count; + } +} diff --git a/Easy/Count Integers With Even Digit Sum.java b/Easy/Count Integers With Even Digit Sum.java new file mode 100644 index 00000000..172a17d3 --- /dev/null +++ b/Easy/Count Integers With Even Digit Sum.java @@ -0,0 +1,14 @@ +class Solution { + public int countEven(int num) { + return (int) IntStream.range(1, num + 1).boxed().filter(this::isSumOfDigitsEven).count(); + } + + private boolean isSumOfDigitsEven(int num) { + int sum = 0; + while (num > 0) { + sum += num % 10; + num /= 10; + } + return sum % 2 == 0; + } +} diff --git a/Easy/Count Items Matching a Rule.java b/Easy/Count Items Matching a Rule.java new file mode 100644 index 00000000..3ce28691 --- /dev/null +++ b/Easy/Count Items Matching a Rule.java @@ -0,0 +1,6 @@ +class Solution { + public int countMatches(List> items, String ruleKey, String ruleValue) { + int ruleIdx = ruleKey.equals("type") ? 0 : (ruleKey.equals("color") ? 1 : 2); + return (int) items.stream().filter(item -> item.get(ruleIdx).equals(ruleValue)).count(); + } +} diff --git a/Easy/Count Negative Numbers in a Sorted Matrix.java b/Easy/Count Negative Numbers in a Sorted Matrix.java index 96daf80b..af842b43 100644 --- a/Easy/Count Negative Numbers in a Sorted Matrix.java +++ b/Easy/Count Negative Numbers in a Sorted Matrix.java @@ -1,28 +1,26 @@ class Solution { - public int countNegatives(int[][] grid) { - int total = 0; - int n = grid[0].length; - for (int[] gr : grid) { - int negInd = binarySearchHelper(gr, 0, n - 1); - if (negInd != -1) { - total += n - negInd; - } + public int countNegatives(int[][] grid) { + int count = 0; + for (int[] row : grid) { + int idx = findFirstNonNegativeIndex(row); + count += idx == -1 ? 0 : (row.length - idx); + } + return count; } - return total; - } - - private int binarySearchHelper(int[] arr, int start, int end) { - int idx = -1; - while (start <= end) { - int mid = (start + end) / 2; - if (arr[mid] < 0) { - idx = idx == -1 ? mid : Math.min(idx, mid); - end = mid - 1; - } - if (arr[mid] >= 0) { - start = mid + 1; - } + + private int findFirstNonNegativeIndex(int[] row) { + int start = 0; + int end = row.length - 1; + int idx = -1; + while (start <= end) { + int mid = (start + end) / 2; + if (row[mid] < 0) { + idx = mid; + end = mid - 1; + } else { + start = mid + 1; + } + } + return idx; } - return idx; - } } diff --git a/Easy/Count Number of Pairs With Absolute Difference K.java b/Easy/Count Number of Pairs With Absolute Difference K.java new file mode 100644 index 00000000..8ff77d76 --- /dev/null +++ b/Easy/Count Number of Pairs With Absolute Difference K.java @@ -0,0 +1,12 @@ +class Solution { + public int countKDifference(int[] nums, int k) { + int count = 0; + Map map = new HashMap<>(); + for (int num : nums) { + count += map.getOrDefault(num + k, 0); + count += map.getOrDefault(num - k, 0); + map.put(num, map.getOrDefault(num, 0) + 1); + } + return count; + } +} diff --git a/Easy/Count Odd Numbers in an Interval Range.java b/Easy/Count Odd Numbers in an Interval Range.java index 68fe1652..7155bbc8 100644 --- a/Easy/Count Odd Numbers in an Interval Range.java +++ b/Easy/Count Odd Numbers in an Interval Range.java @@ -1,5 +1,5 @@ class Solution { public int countOdds(int low, int high) { - return (high + 1) / 2 - low / 2; + return (high - low) / 2 + (low % 2 != 0 || high % 2 != 0 ? 1 : 0); } } diff --git a/Easy/Count Operations to Obtain Zero.java b/Easy/Count Operations to Obtain Zero.java new file mode 100644 index 00000000..7f1678c6 --- /dev/null +++ b/Easy/Count Operations to Obtain Zero.java @@ -0,0 +1,14 @@ +class Solution { + public int countOperations(int num1, int num2) { + int numOfOperations = 0; + while (num1 != 0 && num2 != 0) { + if (num1 >= num2) { + num1 -= num2; + } else { + num2 -= num1; + } + numOfOperations++; + } + return numOfOperations; + } +} diff --git a/Easy/Count Pairs Of Similar Strings.java b/Easy/Count Pairs Of Similar Strings.java new file mode 100644 index 00000000..d9b1f7f9 --- /dev/null +++ b/Easy/Count Pairs Of Similar Strings.java @@ -0,0 +1,26 @@ +class Solution { + public int similarPairs(String[] words) { + Map map = new HashMap<>(); + int pairCount = 0; + for (String word : words) { + String key = buildSortedCharString(word); + pairCount += map.getOrDefault(key, 0); + map.put(key, map.getOrDefault(key, 0) + 1); + } + return pairCount; + } + + private static String buildSortedCharString(String s) { + boolean[] exists = new boolean[26]; + for (char c : s.toCharArray()) { + exists[c - 'a'] = true; + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 26; i++) { + if (exists[i]) { + sb.append((char) (97 + i)); + } + } + return sb.toString(); + } +} diff --git a/Easy/Count Pairs That Form a Complete Day I.java b/Easy/Count Pairs That Form a Complete Day I.java new file mode 100644 index 00000000..785a5937 --- /dev/null +++ b/Easy/Count Pairs That Form a Complete Day I.java @@ -0,0 +1,11 @@ +class Solution { + public int countCompleteDayPairs(int[] hours) { + int count = 0; + Map map = new HashMap<>(); + for (int hour : hours) { + count += map.getOrDefault((24 - hour % 24) % 24, 0); + map.put(hour % 24, map.getOrDefault(hour % 24, 0) + 1); + } + return count; + } +} diff --git a/Easy/Count Pairs Whose Sum is Less than Target.java b/Easy/Count Pairs Whose Sum is Less than Target.java new file mode 100644 index 00000000..90c31c23 --- /dev/null +++ b/Easy/Count Pairs Whose Sum is Less than Target.java @@ -0,0 +1,18 @@ +class Solution { + public int countPairs(List nums, int target) { + Collections.sort(nums); + int start = 0; + int end = nums.size() - 1; + int count = 0; + while (start < end) { + int sum = nums.get(start) + nums.get(end); + if (sum < target) { + count += end - start; + start++; + } else { + end--; + } + } + return count; + } +} diff --git a/Easy/Count Partitions with Even Sum Difference.java b/Easy/Count Partitions with Even Sum Difference.java new file mode 100644 index 00000000..0390a5a1 --- /dev/null +++ b/Easy/Count Partitions with Even Sum Difference.java @@ -0,0 +1,17 @@ +class Solution { + public int countPartitions(int[] nums) { + int n = nums.length; + int[] prefixSum = new int[n]; + for (int i = 0; i < n; i++) { + prefixSum[i] = nums[i]; + prefixSum[i] += i == 0 ? 0 : prefixSum[i - 1]; + } + int partitions = 0; + for (int i = 0; i < n - 1; i++) { + int leftSum = prefixSum[i]; + int rightSum = prefixSum[n - 1] - prefixSum[i]; + partitions += (rightSum - leftSum) % 2 == 0 ? 1 : 0; + } + return partitions; + } +} diff --git a/Easy/Count Prefix and Suffix Pairs I.java b/Easy/Count Prefix and Suffix Pairs I.java new file mode 100644 index 00000000..919d41d1 --- /dev/null +++ b/Easy/Count Prefix and Suffix Pairs I.java @@ -0,0 +1,14 @@ +class Solution { + public int countPrefixSuffixPairs(String[] words) { + int count = 0; + for (int i = 0; i < words.length; i++) { + String target = words[i]; + for (int j = i + 1; j < words.length; j++) { + if (words[j].startsWith(target) && words[j].endsWith(target)) { + count++; + } + } + } + return count; + } +} diff --git a/Easy/Count Prefixes of a Given String.java b/Easy/Count Prefixes of a Given String.java new file mode 100644 index 00000000..52438307 --- /dev/null +++ b/Easy/Count Prefixes of a Given String.java @@ -0,0 +1,5 @@ +class Solution { + public int countPrefixes(String[] words, String s) { + return (int) Arrays.stream(words).filter(word -> s.startsWith(word)).count(); + } +} diff --git a/Easy/Count Primes.java b/Easy/Count Primes.java index e6cbb56b..4f1f9ec1 100644 --- a/Easy/Count Primes.java +++ b/Easy/Count Primes.java @@ -1,23 +1,21 @@ class Solution { - public int countPrimes(int n) { - int[] arr = new int[n]; - - for (int i=2;i e != -1).count(); + } + + private void populateSieveArray(int[] nums) { + Arrays.fill(nums, 0, 2, -1); + for (int i = 2; i < nums.length; i++) { + if (nums[i] != -1) { + for (int j = i + i; j < nums.length; j += i) { + nums[j] = -1; } - - return count; + } } + } } diff --git a/Easy/Count Special Quadruplets.java b/Easy/Count Special Quadruplets.java new file mode 100644 index 00000000..1c1cdb71 --- /dev/null +++ b/Easy/Count Special Quadruplets.java @@ -0,0 +1,18 @@ +class Solution { + public int countQuadruplets(int[] nums) { + Map map = new HashMap<>(); + int count = 0; + map.put(nums[nums.length - 1], 1); + for (int i = nums.length - 2; i > 1; i--) { + for (int j = i - 1; j > 0; j--) { + for (int k = j - 1; k >= 0; k--) { + if (map.containsKey(nums[i] + nums[j] + nums[k])) { + count += map.get(nums[i] + nums[j] + nums[k]); + } + } + } + map.put(nums[i], map.getOrDefault(nums[i], 0) + 1); + } + return count; + } +} diff --git a/Easy/Count Square Sum Triples.java b/Easy/Count Square Sum Triples.java new file mode 100644 index 00000000..a7c47e94 --- /dev/null +++ b/Easy/Count Square Sum Triples.java @@ -0,0 +1,18 @@ +class Solution { + public int countTriples(int n) { + Map map = new HashMap<>(); + for (int i = 1; i <= n; i++) { + map.put(i*i, i); + } + int count = 0; + for (int i = 1; i <= n; i++) { + for (int j = i + 1; j <= n; j++) { + int key = i * i + j * j; + if (map.containsKey(key) && !map.get(key).equals(i) && !map.get(key).equals(j)) { + count += 2; + } + } + } + return count; + } +} diff --git a/Easy/Count Subarrays of Length Three With a Condition.java b/Easy/Count Subarrays of Length Three With a Condition.java new file mode 100644 index 00000000..4694fb65 --- /dev/null +++ b/Easy/Count Subarrays of Length Three With a Condition.java @@ -0,0 +1,11 @@ +class Solution { + public int countSubarrays(int[] nums) { + int count = 0; + for (int i = 0; i < nums.length - 2; i++) { + if (2 * (nums[i] + nums[i + 2]) == nums[i + 1]) { + count++; + } + } + return count; + } +} diff --git a/Easy/Count Substrings That Satisfy K-Constraint I.java b/Easy/Count Substrings That Satisfy K-Constraint I.java new file mode 100644 index 00000000..9f44425d --- /dev/null +++ b/Easy/Count Substrings That Satisfy K-Constraint I.java @@ -0,0 +1,21 @@ +class Solution { + public int countKConstraintSubstrings(String s, int k) { + Map map = new HashMap<>(); + int start = 0; + int end = 0; + int n = s.length(); + int result = 0; + while (end < n) { + map.put(s.charAt(end), map.getOrDefault(s.charAt(end), 0) + 1); + end++; + while (start < end && map.getOrDefault('0', 0) > k && map.getOrDefault('1', 0) > k) { + map.put(s.charAt(start), map.get(s.charAt(start)) - 1); + start++; + } + if (map.getOrDefault('0', 0) <= k || map.getOrDefault('1', 0) <= k) { + result += end - start; + } + } + return result; + } +} diff --git a/Easy/Count Symmetric Integers.java b/Easy/Count Symmetric Integers.java new file mode 100644 index 00000000..8ae9c320 --- /dev/null +++ b/Easy/Count Symmetric Integers.java @@ -0,0 +1,27 @@ +class Solution { + public int countSymmetricIntegers(int low, int high) { + int count = 0; + for (int i = low; i <= high; i++) { + if (isSymmetric(i)) { + count++; + } + } + return count; + } + + private static boolean isSymmetric(int num) { + String s = String.valueOf(num); + int n = s.length(); + if (n % 2 != 0) { + return false; + } + int sum = 0; + for (int i = 0; i < n / 2; i++) { + sum += Character.getNumericValue(s.charAt(i)); + } + for (int i = n / 2; i < n; i++) { + sum -= Character.getNumericValue(s.charAt(i)); + } + return sum == 0; + } +} diff --git a/Easy/Count Tested Devices After Test Operations.java b/Easy/Count Tested Devices After Test Operations.java new file mode 100644 index 00000000..1f6cdb0f --- /dev/null +++ b/Easy/Count Tested Devices After Test Operations.java @@ -0,0 +1,13 @@ +class Solution { + public int countTestedDevices(int[] batteryPercentages) { + int count = 0; + int diff = 0; + for (int batteryPercentage : batteryPercentages) { + if (Math.max(0, batteryPercentage - diff) > 0) { + count++; + diff++; + } + } + return count; + } +} diff --git a/Easy/Count Vowel Substrings of a String.java b/Easy/Count Vowel Substrings of a String.java new file mode 100644 index 00000000..93ddc212 --- /dev/null +++ b/Easy/Count Vowel Substrings of a String.java @@ -0,0 +1,32 @@ +class Solution { + public int countVowelSubstrings(String word) { + return atMostVowel(word, 5) - atMostVowel(word, 4); + } + + private int atMostVowel(String word, int atMostGoal) { + int start = 0; + int count = 0; + int n = word.length(); + Map map = new HashMap<>(); + for (int end = 0; end < n; end++) { + if (!isVowel(word.charAt(end))) { + map.clear(); + start = end + 1; + } else { + map.put(word.charAt(end), map.getOrDefault(word.charAt(end), 0) + 1); + for (; map.size() > atMostGoal; start++) { + map.put(word.charAt(start), map.get(word.charAt(start)) - 1); + if (map.get(word.charAt(start)) == 0) { + map.remove(word.charAt(start)); + } + } + count += end - start + 1; + } + } + return count; + } + + private boolean isVowel(char c) { + return "aeiou".indexOf(c) != -1; + } +} diff --git a/Easy/Count and Say.java b/Easy/Count and Say.java deleted file mode 100644 index 7f2eed96..00000000 --- a/Easy/Count and Say.java +++ /dev/null @@ -1,23 +0,0 @@ -class Solution { - public String countAndSay(int n) { - return rec(n, "1"); - } - - private String rec(int n, String s) { - if (n == 1) { - return s; - } - StringBuilder sb = new StringBuilder(); - int idx = 0; - while (idx < s.length()) { - char c = s.charAt(idx); - int count = 0; - while (idx < s.length() && s.charAt(idx) == c) { - idx++; - count++; - } - sb.append(count).append(c); - } - return rec(n - 1, sb.toString()); - } -} diff --git a/Easy/Count of Matches in Tournament.java b/Easy/Count of Matches in Tournament.java new file mode 100644 index 00000000..1fc5a6e4 --- /dev/null +++ b/Easy/Count of Matches in Tournament.java @@ -0,0 +1,10 @@ +class Solution { + public int numberOfMatches(int n) { + int numOfMatches = 0; + while (n > 1) { + numOfMatches += n / 2; + n = n / 2 + n % 2; + } + return numOfMatches; + } +} diff --git a/Easy/Count the Digits That Divide a Number.java b/Easy/Count the Digits That Divide a Number.java new file mode 100644 index 00000000..085c312b --- /dev/null +++ b/Easy/Count the Digits That Divide a Number.java @@ -0,0 +1,14 @@ +class Solution { + public int countDigits(int num) { + int count = 0; + int copy = num; + while (num > 0) { + int digit = num % 10; + num /= 10; + if (digit != 0 && copy % digit == 0) { + count++; + } + } + return count; + } +} diff --git a/Easy/Count the Number of Consistent Strings.java b/Easy/Count the Number of Consistent Strings.java new file mode 100644 index 00000000..24aad751 --- /dev/null +++ b/Easy/Count the Number of Consistent Strings.java @@ -0,0 +1,10 @@ +class Solution { + public int countConsistentStrings(String allowed, String[] words) { + return (int) + Arrays.stream(words) + .filter( + word -> + word.chars().mapToObj(c -> (char) c).allMatch(c -> allowed.indexOf(c) != -1)) + .count(); + } +} diff --git a/Easy/Count the Number of Special Characters I.java b/Easy/Count the Number of Special Characters I.java new file mode 100644 index 00000000..44c9950f --- /dev/null +++ b/Easy/Count the Number of Special Characters I.java @@ -0,0 +1,20 @@ +class Solution { + public int numberOfSpecialChars(String word) { + boolean[] upperPresent = new boolean[26]; + boolean[] lowerPresent = new boolean[26]; + for (char c : word.toCharArray()) { + if (Character.isUpperCase(c)) { + upperPresent[c - 'A'] = true; + } else { + lowerPresent[c - 'a'] = true; + } + } + int count = 0; + for (int i = 0; i < 26; i++) { + if (upperPresent[i] && lowerPresent[i]) { + count++; + } + } + return count; + } +} diff --git a/Easy/Count the Number of Vowel Strings in Range.java b/Easy/Count the Number of Vowel Strings in Range.java new file mode 100644 index 00000000..38eeb76e --- /dev/null +++ b/Easy/Count the Number of Vowel Strings in Range.java @@ -0,0 +1,10 @@ +class Solution { + public int vowelStrings(String[] words, int left, int right) { + Set vowels = Set.of('a', 'e', 'i', 'o', 'u'); + return (int) Arrays.stream(words) + .skip(left) + .limit(right - left + 1) + .filter(word -> vowels.contains(word.charAt(0)) && vowels.contains(word.charAt(word.length() - 1))) + .count(); + } +} diff --git a/Easy/Counting Bits.java b/Easy/Counting Bits.java new file mode 100644 index 00000000..4b5c69fa --- /dev/null +++ b/Easy/Counting Bits.java @@ -0,0 +1,9 @@ +class Solution { + public int[] countBits(int n) { + int[] result = new int[n + 1]; + for (int i = 1; i <= n; i++) { + result[i] = result[i / 2] + i % 2; + } + return result; + } +} diff --git a/Easy/Counting Words With a Given Prefix.java b/Easy/Counting Words With a Given Prefix.java new file mode 100644 index 00000000..b3ed8f47 --- /dev/null +++ b/Easy/Counting Words With a Given Prefix.java @@ -0,0 +1,5 @@ +class Solution { + public int prefixCount(String[] words, String pref) { + return (int) Arrays.stream(words).filter(w -> w.startsWith(pref)).count(); + } +} diff --git a/Easy/Cousins in Binary Tree.java b/Easy/Cousins in Binary Tree.java index 21c6431d..f2325e25 100644 --- a/Easy/Cousins in Binary Tree.java +++ b/Easy/Cousins in Binary Tree.java @@ -15,27 +15,32 @@ */ class Solution { public boolean isCousins(TreeNode root, int x, int y) { - int[] depthAndParentX = {0, 0}; - int[] depthAndParentY = {0, 0}; - helper(root, x, 0, null, depthAndParentX); - helper(root, y, 0, null, depthAndParentY); - return depthAndParentX[0] == depthAndParentY[0] && depthAndParentX[1] != depthAndParentY[1]; + ParentDepthPair xPair = getParentDepthPair(root, x, 0); + ParentDepthPair yPair = getParentDepthPair(root, y, 0); + return xPair.parent != yPair.parent && xPair.depth == yPair.depth; } - private void helper( - TreeNode root, int num, int currDepth, TreeNode currParent, int[] depthAndParent - ) { + private ParentDepthPair getParentDepthPair(TreeNode root, int val, int currDepth) { if (root == null) { - return; + return null; } - if (root.val == num) { - System.out.println(root.val + " " + num + " " + (currParent == null ? -1 : currParent.val)); - depthAndParent[0] = currDepth; - depthAndParent[1] = currParent == null ? -1 : currParent.val; + if (root.val == val) { + return new ParentDepthPair(root, currDepth); } - else { - helper(root.left, num, currDepth + 1, root, depthAndParent); - helper(root.right, num, currDepth + 1, root, depthAndParent); + if ((root.left != null && root.left.val == val) || (root.right != null && root.right.val == val)) { + return new ParentDepthPair(root, currDepth); + } + ParentDepthPair leftPair = getParentDepthPair(root.left, val, currDepth + 1); + return leftPair != null ? leftPair : getParentDepthPair(root.right, val, currDepth + 1); + } + + private static class ParentDepthPair { + TreeNode parent; + int depth; + + public ParentDepthPair(TreeNode parent, int depth) { + this.parent = parent; + this.depth = depth; } } } diff --git a/Easy/Decode XORed Array.java b/Easy/Decode XORed Array.java new file mode 100644 index 00000000..fa9442a4 --- /dev/null +++ b/Easy/Decode XORed Array.java @@ -0,0 +1,10 @@ +class Solution { + public int[] decode(int[] encoded, int first) { + int[] ans = new int[encoded.length + 1]; + ans[0] = first; + for (int i = 0; i < encoded.length; i++) { + ans[i + 1] = ans[i] ^ encoded[i]; + } + return ans; + } +} diff --git a/Easy/Decode the Message.java b/Easy/Decode the Message.java new file mode 100644 index 00000000..c7396320 --- /dev/null +++ b/Easy/Decode the Message.java @@ -0,0 +1,16 @@ +class Solution { + public String decodeMessage(String key, String message) { + int counter = 0; + Map map = new HashMap<>(); + for (char c : key.toCharArray()) { + if (!map.containsKey(c) && c != ' ') { + map.put(c, (char) ('a' + counter++)); + } + } + StringBuilder sb = new StringBuilder(); + for (char c : message.toCharArray()) { + sb.append(c == ' ' ? ' ' : map.get(c)); + } + return sb.toString(); + } +} diff --git a/Easy/Defuse the Bomb.java b/Easy/Defuse the Bomb.java new file mode 100644 index 00000000..502f887c --- /dev/null +++ b/Easy/Defuse the Bomb.java @@ -0,0 +1,18 @@ +class Solution { + public int[] decrypt(int[] code, int k) { + int n = code.length; + int[] result = new int[n]; + for (int i = 0; i < n; i++) { + if (k > 0) { + for (int j = i + 1; j < i + k + 1; j++) { + result[i] += code[j % n]; + } + } else if (k < 0) { + for (int j = i - 1; j > i + k - 1; j--) { + result[i] += code[(j + n) % n]; + } + } + } + return result; + } +} diff --git a/Easy/Degree of an array.java b/Easy/Degree of an array.java index f4c3f2f3..85c1622e 100644 --- a/Easy/Degree of an array.java +++ b/Easy/Degree of an array.java @@ -1,24 +1,24 @@ class Solution { public int findShortestSubArray(int[] nums) { - Map count = new HashMap<>(); - Map left = new HashMap<>(); - Map right = new HashMap<>(); - int degree = 0; - for (int i = 0; i < nums.length; i++) { - int num = nums[i]; - if (!left.containsKey(num)) { - left.put(num, i); - } - right.put(num, i); - count.put(num, count.getOrDefault(num, 0) + 1); - degree = Math.max(degree, count.get(num)); + Map map = new HashMap<>(); + int maxCount = 0; + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + maxCount = Math.max(maxCount, map.get(num)); } - int ans = nums.length; - for (int key : count.keySet()) { - if (count.get(key) == degree) { - ans = Math.min(ans, right.get(key) - left.get(key) + 1); + int start = 0; + int end = 0; + map.clear(); + int minLength = Integer.MAX_VALUE; + while (end < nums.length) { + map.put(nums[end], map.getOrDefault(nums[end], 0) + 1); + while (start <= end && map.get(nums[end]) == maxCount) { + minLength = Math.min(minLength, end - start + 1); + map.put(nums[start], map.get(nums[start]) - 1); + start++; } + end++; } - return ans; + return minLength; } } diff --git a/Easy/Delete Characters to Make Fancy String.java b/Easy/Delete Characters to Make Fancy String.java new file mode 100644 index 00000000..ff26a1b4 --- /dev/null +++ b/Easy/Delete Characters to Make Fancy String.java @@ -0,0 +1,18 @@ +class Solution { + public String makeFancyString(String s) { + int idx = 0; + StringBuilder sb = new StringBuilder(); + while (idx < s.length()) { + char c = s.charAt(idx); + int count = 0; + while (idx < s.length() && s.charAt(idx) == c) { + idx++; + count++; + if (count <= 2) { + sb.append(c); + } + } + } + return sb.toString(); + } +} diff --git a/Easy/Delete Greatest Value in Each Row.java b/Easy/Delete Greatest Value in Each Row.java new file mode 100644 index 00000000..ca6794aa --- /dev/null +++ b/Easy/Delete Greatest Value in Each Row.java @@ -0,0 +1,16 @@ +class Solution { + public int deleteGreatestValue(int[][] grid) { + for (int[] g : grid) { + Arrays.sort(g); + } + int result = 0; + for (int i = grid[0].length - 1; i >= 0; i--) { + int maxValue = Integer.MIN_VALUE; + for (int[] g : grid) { + maxValue = Math.max(maxValue, g[i]); + } + result += maxValue; + } + return result; + } +} diff --git a/Easy/Delete Node in a Linked List.java b/Easy/Delete Node in a Linked List.java new file mode 100644 index 00000000..0cfa6304 --- /dev/null +++ b/Easy/Delete Node in a Linked List.java @@ -0,0 +1,15 @@ +/** +* Definition for singly-linked list. +* public class ListNode { +* int val; +* ListNode next; +* ListNode(int x) { val = x; } +* } +*/ +class Solution { + public void deleteNode(ListNode node) { + int nextVal = node.next.val; + node.next = node.next.next; + node.val = nextVal; + } +} diff --git a/Easy/Delete node in a linked list.java b/Easy/Delete node in a linked list.java deleted file mode 100644 index 3704d05b..00000000 --- a/Easy/Delete node in a linked list.java +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode(int x) { val = x; } - * } - */ -class Solution { - public void deleteNode(ListNode node) { - node.val = node.next.val; - node.next=node.next.next; - } -} \ No newline at end of file diff --git a/Easy/Design Compressed String Iterator.java b/Easy/Design Compressed String Iterator.java index 8d128e75..a13e5d9e 100644 --- a/Easy/Design Compressed String Iterator.java +++ b/Easy/Design Compressed String Iterator.java @@ -1,61 +1,49 @@ class StringIterator { - int letterPointer = 0; - int numberPointer = letterPointer + 1; - int counter; - char c; - String s; - StringBuilder num; - public StringIterator(String compressedString) { - s = compressedString; - c = s.charAt(letterPointer); - - num = new StringBuilder(); - while (numberPointer s.length()-1) { - return false; - } - } - return true; + public boolean hasNext() { + updateCurrCount(); + return this.currCount > 0; + } + + private void updateCurrCount() { + if (this.currCount != null && this.currCount == 0) { + this.charIdx = this.counterIdx; + this.counterIdx = this.charIdx + 1; } + if (this.currCount == null) { + this.charIdx = 0; + this.counterIdx = this.charIdx + 1; + this.currCount = 0; + } + if (this.currCount == 0) { + while (this.counterIdx < this.s.length() + && Character.isDigit(this.s.charAt(this.counterIdx))) { + this.currCount = + this.currCount * 10 + Character.getNumericValue(this.s.charAt(this.counterIdx++)); + } + } + } } + /** * Your StringIterator object will be instantiated and called as such: * StringIterator obj = new StringIterator(compressedString); diff --git a/Easy/Design HashMap.java b/Easy/Design HashMap.java index d59fe9e1..ff29c920 100644 --- a/Easy/Design HashMap.java +++ b/Easy/Design HashMap.java @@ -1,42 +1,40 @@ class MyHashMap { - /** Initialize your data structure here. */ - Integer[][] map; - int NUM_OF_BUCKETS = 1000; - int BUCKET_SIZE = 1000; - public MyHashMap() { - map = new Integer[NUM_OF_BUCKETS][BUCKET_SIZE]; - } + private static final int BUCKET_COUNT = 1001; - /** value will always be non-negative. */ - public void put(int key, int value) { - Integer[] bucket = getBucket(key); - int keyHash = getKeyHash(key); - bucket[keyHash] = value; - } + private static final int BUCKET_SIZE = 1001; - /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */ - public int get(int key) { - Integer[] bucket = getBucket(key); - int keyHash = getKeyHash(key); - return bucket[keyHash] == null ? -1 : bucket[keyHash]; - } + private final Integer[][] map; - /** Removes the mapping of the specified value key if this map contains a mapping for the key */ - public void remove(int key) { - Integer[] bucket = getBucket(key); - int keyHash = getKeyHash(key); - bucket[keyHash] = null; - } - - private Integer[] getBucket(int key) { - int bucketIdx = key / BUCKET_SIZE; - return map[bucketIdx]; - } - - private Integer getKeyHash(int key) { - return key % BUCKET_SIZE; - } + public MyHashMap() { + this.map = new Integer[BUCKET_COUNT][BUCKET_SIZE]; + } + + public void put(int key, int value) { + Position position = getPosition(key); + map[position.bucket()][position.index()] = value; + } + + public int get(int key) { + Position position = getPosition(key); + Integer value = map[position.bucket()][position.index()]; + return value == null ? -1 : value; + } + + public void remove(int key) { + Position position = getPosition(key); + map[position.bucket()][position.index()] = null; + } + + private static Position getPosition(int key) { + int bucket = key / BUCKET_COUNT; + int index = key % BUCKET_SIZE; + return new Position(bucket, index); + } + + private static record Position(int bucket, int index) { + + } } /** diff --git a/Easy/Design Linked List.java b/Easy/Design Linked List.java index 50533d0a..1f59ba54 100644 --- a/Easy/Design Linked List.java +++ b/Easy/Design Linked List.java @@ -1,106 +1,88 @@ class MyLinkedList { + + private Node head; + private Node tail; + private int count; + + public MyLinkedList() { + this.head = new Node(-1); + this.tail = new Node(-1); + head.next = tail; + tail.prev = head; + this.count = 0; + } - /** Initialize your data structure here. */ - Node head; - Node tail; - int count; - public MyLinkedList() { - head = new Node(-1); - tail = new Node(-1); - head.next = tail; - tail.prev = head; - count = 0; - } - - /** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */ - public int get(int index) { - if (index < 0 || index >= count) { - return -1; - } - Node curr = head.next; - int idx = 0; - while (idx < index) { - idx++; - curr = curr.next; - } - return curr.val; - } - - /** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */ - public void addAtHead(int val) { - Node newNode = new Node(val); - newNode.next = head.next; - newNode.prev = head; - head.next.prev = newNode; - head.next = newNode; - count++; + public int get(int index) { + Node node = getNode(index); + return node == null ? -1 : node.val; + } + + public void addAtHead(int val) { + Node node = new Node(val); + Node nextNode = head.next; + node.next = nextNode; + node.prev = head; + nextNode.prev = node; + head.next = node; + count++; + } + + public void addAtTail(int val) { + Node node = new Node(val); + Node prevNode = tail.prev; + node.next = tail; + tail.prev = node; + prevNode.next = node; + node.prev = prevNode; + count++; + } + + public void addAtIndex(int index, int val) { + if (index == count) { + addAtTail(val); + } else if (index < count) { + Node nodeAtIndex = getNode(index); + Node prevNode = nodeAtIndex.prev; + Node node = new Node(val); + node.prev = prevNode; + prevNode.next = node; + node.next = nodeAtIndex; + nodeAtIndex.prev = node; + count++; } - - /** Append a node of value val to the last element of the linked list. */ - public void addAtTail(int val) { - Node newNode = new Node(val); - newNode.prev = tail.prev; - newNode.next = tail; - tail.prev.next = newNode; - tail.prev = newNode; - count++; + } + + public void deleteAtIndex(int index) { + Node node = getNode(index); + if (node != null) { + Node prevNode = node.prev; + Node nextNode = node.next; + prevNode.next = nextNode; + nextNode.prev = prevNode; + count--; } - - /** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */ - public void addAtIndex(int index, int val) { - if (index < 0 || index > count) { - return; - } - if (index == 0) { - addAtHead(val); - } - else if (index == count) { - addAtTail(val); - } - else { - int idx = 0; - Node curr = head; - while (idx < index) { - idx++; - curr = curr.next; - } - Node newNode = new Node(val); - newNode.prev = curr; - newNode.next = curr.next; - curr.next.prev = newNode; - curr.next = newNode; - count++; - } + } + + private Node getNode(int index) { + if (index >= count) { + return null; } - - /** Delete the index-th node in the linked list, if the index is valid. */ - public void deleteAtIndex(int index) { - if (index < 0 || index >= count) { - return; - } - int idx = 0; - Node curr = head; - while (idx < index) { - idx++; - curr = curr.next; - } - Node next = curr.next.next; - next.prev = curr; - curr.next = next; - count--; + Node curr = head.next; + for (int i = 0; i < index; i++) { + curr = curr.next; } -} - -class Node { + return curr; + } + + private static class Node { int val; Node next; Node prev; public Node(int val) { - this.val = val; - next = null; - prev = null; + this.val = val; } + } } /** diff --git a/Easy/Design Neighbor Sum Service.java b/Easy/Design Neighbor Sum Service.java new file mode 100644 index 00000000..93446e53 --- /dev/null +++ b/Easy/Design Neighbor Sum Service.java @@ -0,0 +1,50 @@ +class neighborSum { + + private static final int[][] ADJACENT_DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + private static final int[][] DIAGONAL_DIRS = {{1, -1}, {-1, 1}, {1, 1}, {-1, -1}}; + + private final int[][] grid; + private final int numRows; + private final int numCols; + private final Map valueToCoordinateMap; + + public neighborSum(int[][] grid) { + this.numRows = grid.length; + this.numCols = grid[0].length; + this.valueToCoordinateMap = new HashMap<>(); + this.grid = new int[numRows][numCols]; + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numCols; j++) { + this.grid[i][j] = grid[i][j]; + this.valueToCoordinateMap.put(grid[i][j], new int[]{i, j}); + } + } + } + + public int adjacentSum(int value) { + return calculateSum(valueToCoordinateMap.get(value), ADJACENT_DIRS); + } + + public int diagonalSum(int value) { + return calculateSum(valueToCoordinateMap.get(value), DIAGONAL_DIRS); + } + + private int calculateSum(int[] coordinate, int[][] directions) { + int sum = 0; + for (int[] dir : directions) { + int newX = dir[0] + coordinate[0]; + int newY = dir[1] + coordinate[1]; + if (newX >= 0 && newX < numRows && newY >= 0 && newY < numCols) { + sum += grid[newX][newY]; + } + } + return sum; + } +} + +/** + * Your neighborSum object will be instantiated and called as such: + * neighborSum obj = new neighborSum(grid); + * int param_1 = obj.adjacentSum(value); + * int param_2 = obj.diagonalSum(value); + */ diff --git a/Easy/Design Parking System.java b/Easy/Design Parking System.java index 6aa29a71..331e14fc 100644 --- a/Easy/Design Parking System.java +++ b/Easy/Design Parking System.java @@ -1,15 +1,12 @@ class ParkingSystem { - int[] slots; + + private int[] availableSpaces; public ParkingSystem(int big, int medium, int small) { - slots = new int[]{big, medium, small}; + this.availableSpaces = new int[]{big, medium, small}; } public boolean addCar(int carType) { - if (slots[carType - 1] == 0) { - return false; - } - slots[carType - 1]--; - return true; + return this.availableSpaces[carType - 1]-- > 0; } } diff --git a/Easy/Design an Ordered Stream.java b/Easy/Design an Ordered Stream.java new file mode 100644 index 00000000..68c1eba7 --- /dev/null +++ b/Easy/Design an Ordered Stream.java @@ -0,0 +1,23 @@ +class OrderedStream { + private String[] stream; + private int currIdx; + public OrderedStream(int n) { + this.stream = new String[n]; + this.currIdx = 0; + } + + public List insert(int idKey, String value) { + this.stream[idKey - 1] = value; + List result = new ArrayList<>(); + while (this.currIdx < stream.length && this.stream[this.currIdx] != null) { + result.add(this.stream[this.currIdx++]); + } + return result; + } +} + +/** + * Your OrderedStream object will be instantiated and called as such: + * OrderedStream obj = new OrderedStream(n); + * List param_1 = obj.insert(idKey,value); + */ diff --git a/Easy/Design an Ordered System.java b/Easy/Design an Ordered System.java new file mode 100644 index 00000000..e6427b9f --- /dev/null +++ b/Easy/Design an Ordered System.java @@ -0,0 +1,23 @@ +class OrderedStream { + int ptr; + String[] map; + public OrderedStream(int n) { + map = new String[n]; + ptr = 0; + } + + public List insert(int id, String value) { + List list = new ArrayList<>(); + map[id - 1] = value; + while (ptr < map.length && map[ptr] != null) { + list.add(map[ptr++]); + } + return list; + } +} + +/** + * Your OrderedStream object will be instantiated and called as such: + * OrderedStream obj = new OrderedStream(n); + * List param_1 = obj.insert(id,value); + */ diff --git a/Easy/Destination City.java b/Easy/Destination City.java index c9f08cbc..f6e330ab 100644 --- a/Easy/Destination City.java +++ b/Easy/Destination City.java @@ -1,17 +1,12 @@ class Solution { - public String destCity(List> paths) { - Set outgoingPathCities = new HashSet<>(); - Set cities = new HashSet<>(); - for (List path : paths) { - outgoingPathCities.add(path.get(0)); - cities.add(path.get(0)); - cities.add(path.get(1)); + public String destCity(List> paths) { + Set cities = new HashSet<>(); + Set outgoingCities = new HashSet<>(); + for (List path : paths) { + cities.addAll(path); + outgoingCities.add(path.get(0)); + } + cities.removeAll(outgoingCities); + return cities.iterator().next(); } - for (String city : cities) { - if (!outgoingPathCities.contains(city)) { - return city; - } - } - return ""; - } } diff --git a/Easy/Detect Capital.java b/Easy/Detect Capital.java index dafc6211..863fe0f5 100644 --- a/Easy/Detect Capital.java +++ b/Easy/Detect Capital.java @@ -1,21 +1,21 @@ class Solution { public boolean detectCapitalUse(String word) { - int n = word.length(); - if (n == 0) { - return true; - } - boolean firstCaps = Character.isUpperCase(word.charAt(0)); - for (int i = 1; i < n; i++) { - if (firstCaps) { - if (Character.isUpperCase(word.charAt(1)) && !Character.isUpperCase(word.charAt(i))) { + boolean firstUpperCase = Character.isUpperCase(word.charAt(0)); + boolean allUpperCase = false; + for (int i = 1; i < word.length(); i++) { + if (Character.isUpperCase(word.charAt(i))) { + if (!firstUpperCase) { return false; } - if (!Character.isUpperCase(word.charAt(1)) && Character.isUpperCase(word.charAt(i))) { - return false; + if (i == 1) { + allUpperCase = true; + } else { + if (!allUpperCase) { + return false; + } } - } - else { - if (Character.isUpperCase(word.charAt(i))) { + } else { + if (allUpperCase) { return false; } } diff --git a/Easy/Determine Color of a Chessboard Square.java b/Easy/Determine Color of a Chessboard Square.java new file mode 100644 index 00000000..c18cab14 --- /dev/null +++ b/Easy/Determine Color of a Chessboard Square.java @@ -0,0 +1,10 @@ +class Solution { + public boolean squareIsWhite(String coordinates) { + return ( + ("aceg".indexOf(coordinates.charAt(0)) != -1 + && Character.getNumericValue(coordinates.charAt(1)) % 2 == 0) || + ("aceg".indexOf(coordinates.charAt(0)) == -1 + && Character.getNumericValue(coordinates.charAt(1)) % 2 != 0) + ); + } +} diff --git a/Easy/Determine Whether Matrix Can Be Obtained By Rotation.java b/Easy/Determine Whether Matrix Can Be Obtained By Rotation.java new file mode 100644 index 00000000..7d1d6d46 --- /dev/null +++ b/Easy/Determine Whether Matrix Can Be Obtained By Rotation.java @@ -0,0 +1,39 @@ +class Solution { + public boolean findRotation(int[][] mat, int[][] target) { + for (int i = 0; i < 4; i++) { + if (isEqual(mat, target)) { + return true; + } + rotate(mat); + } + return false; + } + + private boolean isEqual(int[][] mat, int[][] target) { + for (int i = 0; i < mat.length; i++) { + for (int j = 0; j < mat[i].length; j++) { + if (mat[i][j] != target[i][j]) { + return false; + } + } + } + return true; + } + + private void rotate(int[][] mat){ + for(int i = 0; i < mat.length; i++){ + for(int j = i; j < mat[0].length; j++){ + int temp = mat[i][j]; + mat[i][j] = mat[j][i]; + mat[j][i] = temp; + } + } + for(int i = 0; i < mat[0].length / 2; i++){ + for(int j = 0; j < mat.length; j++){ + int temp = mat[j][i]; + mat[j][i] = mat[j][mat[0].length - i - 1]; + mat[j][mat[0].length - i - 1] = temp; + } + } + } +} diff --git a/Easy/Determine if String Halves Are Alike.java b/Easy/Determine if String Halves Are Alike.java new file mode 100644 index 00000000..f7c9a995 --- /dev/null +++ b/Easy/Determine if String Halves Are Alike.java @@ -0,0 +1,20 @@ +class Solution { + + private static final Set VOWELS = Set.of( + 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U' + ); + + public boolean halvesAreAlike(String s) { + int count = 0; + int n = s.length(); + for (int i = 0; i < n / 2; i++) { + if (VOWELS.contains(s.charAt(i))) { + count++; + } + if (VOWELS.contains(s.charAt(i + n / 2))) { + count--; + } + } + return count == 0; + } +} diff --git a/Easy/Determine if Two Events Have Conflict.java b/Easy/Determine if Two Events Have Conflict.java new file mode 100644 index 00000000..66c19dce --- /dev/null +++ b/Easy/Determine if Two Events Have Conflict.java @@ -0,0 +1,14 @@ +class Solution { + public boolean haveConflict(String[] event1, String[] event2) { + int minutesEvent1Start = getMinutes(event1[0]); + int minutesEvent1End = getMinutes(event1[1]); + int minutesEvent2Start = getMinutes(event2[0]); + int minutesEvent2End = getMinutes(event2[1]); + return !(minutesEvent1End < minutesEvent2Start || minutesEvent2End < minutesEvent1Start); + } + + private static int getMinutes(String time) { + String[] split = time.split(":"); + return Integer.parseInt(split[0]) * 60 + Integer.parseInt(split[1]); + } +} diff --git a/Easy/Determine the Winner of a Bowling Game.java b/Easy/Determine the Winner of a Bowling Game.java new file mode 100644 index 00000000..0b64db30 --- /dev/null +++ b/Easy/Determine the Winner of a Bowling Game.java @@ -0,0 +1,25 @@ +class Solution { + public int isWinner(int[] player1, int[] player2) { + int score1 = 0; + int score2 = 0; + int tenIndex1 = -1; + int tenIndex2 = -1; + for (int i = 0; i < player1.length; i++) { + score1 += player1[i]; + score2 += player2[i]; + if (tenIndex1 != -1 && i - tenIndex1 <= 2) { + score1 += player1[i]; + } + if (tenIndex2 != -1 && i - tenIndex2 <= 2) { + score2 += player2[i]; + } + if (player1[i] == 10) { + tenIndex1 = i; + } + if (player2[i] == 10) { + tenIndex2 = i; + } + } + return score1 > score2 ? 1 : (score1 == score2 ? 0 : 2); + } +} diff --git a/Easy/Diameter of Binary Tree.java b/Easy/Diameter of Binary Tree.java index d7e874c7..e62673f3 100644 --- a/Easy/Diameter of Binary Tree.java +++ b/Easy/Diameter of Binary Tree.java @@ -4,25 +4,29 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public int diameterOfBinaryTree(TreeNode root) { - if (root == null) return 0; - - int rootDiam = depth(root.left) + depth(root.right); - int leftDia = diameterOfBinaryTree(root.left); - int rightDia = diameterOfBinaryTree(root.right); - - return Math.max(rootDiam, Math.max(leftDia, rightDia)); - } - - public int depth(TreeNode root) { - if (root == null) { - return 0; - } - - return 1 + Math.max(depth(root.left), depth(root.right)); + public int diameterOfBinaryTree(TreeNode root) { + int[] diameter = {0}; + dfs(root, diameter); + return diameter[0]; + } + + private int dfs(TreeNode root, int[] diameter) { + if (root == null) { + return 0; } + int leftDiameter = dfs(root.left, diameter); + int rightDiameter = dfs(root.right, diameter); + diameter[0] = Math.max(leftDiameter + rightDiameter, diameter[0]); + return Math.max(leftDiameter, rightDiameter) + 1; + } } diff --git a/Easy/Diet Plan Performance.java b/Easy/Diet Plan Performance.java index 719e5797..f2cc1fab 100644 --- a/Easy/Diet Plan Performance.java +++ b/Easy/Diet Plan Performance.java @@ -1,27 +1,16 @@ class Solution { - int points; - public int dietPlanPerformance(int[] calories, int k, int lower, int upper) { - points = 0; - int totalCal = 0; - int start = 0; - for (int i = 0; i < k; i++) { - totalCal += calories[i]; - } - for (int i = k; i < calories.length; i++) { - updatePoints(totalCal, lower, upper); - totalCal -= calories[start++]; - totalCal += calories[i]; - } - updatePoints(totalCal, lower, upper); - return points; + public int dietPlanPerformance(int[] calories, int k, int lower, int upper) { + int points = 0; + int totalCalories = 0; + for (int i = 0; i < k - 1; i++) { + totalCalories += calories[i]; } - - private void updatePoints(int currCal, int lower, int upper) { - if (currCal < lower) { - points--; - } - if (currCal > upper) { - points++; - } + for (int i = k - 1; i < calories.length; i++) { + totalCalories += calories[i]; + points += totalCalories < lower ? -1 : 0; + points += totalCalories > upper ? 1 : 0; + totalCalories -= calories[i - k + 1]; } + return points; + } } diff --git a/Easy/Difference Between Element Sum and Digit Sum of an Array.java b/Easy/Difference Between Element Sum and Digit Sum of an Array.java new file mode 100644 index 00000000..1aef4cbe --- /dev/null +++ b/Easy/Difference Between Element Sum and Digit Sum of an Array.java @@ -0,0 +1,20 @@ +class Solution { + public int differenceOfSum(int[] nums) { + int elementSum = 0; + int digitSum = 0; + for (int num : nums) { + elementSum += num; + digitSum += getDigitSum(num); + } + return Math.abs(elementSum - digitSum); + } + + private static int getDigitSum(int num) { + int sum = 0; + while (num > 0) { + sum += num % 10; + num /= 10; + } + return sum; + } +} diff --git a/Easy/Distribute Candies.java b/Easy/Distribute Candies.java index 65ff099e..0cad02b6 100644 --- a/Easy/Distribute Candies.java +++ b/Easy/Distribute Candies.java @@ -1,15 +1,8 @@ class Solution { - public int distributeCandies(int[] candies) { - Map count = new HashMap<>(); - int unique = 0; - int n = candies.length; - for (int i=0;i n/2 ? n/2 : unique; - } + public int distributeCandies(int[] candyType) { + return Math.min( + Arrays.stream(candyType).boxed().collect(Collectors.toSet()).size(), + candyType.length / 2 + ); + } } diff --git a/Easy/Distribute Elements Into Two Arrays I.java b/Easy/Distribute Elements Into Two Arrays I.java new file mode 100644 index 00000000..9b4bd7d1 --- /dev/null +++ b/Easy/Distribute Elements Into Two Arrays I.java @@ -0,0 +1,26 @@ +class Solution { + public int[] resultArray(int[] nums) { + int start = 0; + int end = nums.length - 1; + int[] result = new int[nums.length]; + result[start++] = nums[0]; + result[end--] = nums[1]; + for (int i = 2; i < nums.length; i++) { + if (result[start - 1] > result[end + 1]) { + result[start++] = nums[i]; + } else { + result[end--] = nums[i]; + } + } + int left = end + 1; + int right = nums.length - 1; + while (left < right) { + int temp = result[left]; + result[left] = result[right]; + result[right] = temp; + left++; + right--; + } + return result; + } +} diff --git a/Easy/Distribute Money to Maximum Children.java b/Easy/Distribute Money to Maximum Children.java new file mode 100644 index 00000000..06dd063f --- /dev/null +++ b/Easy/Distribute Money to Maximum Children.java @@ -0,0 +1,15 @@ +class Solution { + public int distMoney(int money, int children) { + money -= children; + if (money < 0) { + return -1; + } + if (money / 7 == children && money % 7 == 0) { + return children; + } + if (money / 7 == children - 1 && money % 7 == 3) { + return children - 2; + } + return Math.min(children - 1, money / 7); + } +} diff --git a/Easy/Divide Array Into Equal Pairs.java b/Easy/Divide Array Into Equal Pairs.java new file mode 100644 index 00000000..ce8122d3 --- /dev/null +++ b/Easy/Divide Array Into Equal Pairs.java @@ -0,0 +1,8 @@ +class Solution { + public boolean divideArray(int[] nums) { + return Arrays.stream(nums) + .boxed() + .collect(Collectors.groupingBy(Function.identity(), HashMap::new, Collectors.counting())) + .values().stream().allMatch(e -> e % 2 == 0); + } +} diff --git a/Easy/Divide a String Into Groups of Size k.java b/Easy/Divide a String Into Groups of Size k.java new file mode 100644 index 00000000..c37d5a6d --- /dev/null +++ b/Easy/Divide a String Into Groups of Size k.java @@ -0,0 +1,20 @@ +class Solution { + public String[] divideString(String s, int k, char fill) { + int n = s.length() % k == 0 ? s.length() / k : s.length() / k + 1; + String[] result = new String[n]; + int idx = 0; + for (int i = 0; i < n; i++) { + String split = s.substring(idx, Math.min(idx + k, s.length())); + result[i] = formString(split, k, fill); + idx += k; + } + return result; + } + + private String formString(String s, int k, char fill) { + if (s.length() != k) { + return s + String.join("", Collections.nCopies(k - s.length(), String.valueOf(fill))); + } + return s; + } +} diff --git a/Easy/Divide an Array Into Subarrays With Minimum Cost I.java b/Easy/Divide an Array Into Subarrays With Minimum Cost I.java new file mode 100644 index 00000000..7b214fa7 --- /dev/null +++ b/Easy/Divide an Array Into Subarrays With Minimum Cost I.java @@ -0,0 +1,15 @@ +class Solution { + public int minimumCost(int[] nums) { + int minOne = Integer.MAX_VALUE; + int minTwo = Integer.MAX_VALUE; + for (int i = 1; i < nums.length; i++) { + if (nums[i] < minOne) { + minTwo = minOne; + minOne = nums[i]; + } else if (nums[i] < minTwo) { + minTwo = nums[i]; + } + } + return nums[0] + minOne + minTwo; + } +} diff --git a/Easy/Divisible and Non-divisible Sums Difference.java b/Easy/Divisible and Non-divisible Sums Difference.java new file mode 100644 index 00000000..a9c53cc8 --- /dev/null +++ b/Easy/Divisible and Non-divisible Sums Difference.java @@ -0,0 +1,8 @@ +class Solution { + public int differenceOfSums(int n, int m) { + int num1 = n * (n + 1) / 2; + int num2 = n / m; + num2 = m * num2 * (num2 + 1) / 2; + return num1 - 2 * num2; + } +} diff --git a/Easy/Duplicate Zeros.java b/Easy/Duplicate Zeros.java index 54a3592a..9f97be38 100644 --- a/Easy/Duplicate Zeros.java +++ b/Easy/Duplicate Zeros.java @@ -1,23 +1,23 @@ class Solution { - public void duplicateZeros(int[] arr) { - int numOfZeros = 0; - for (int num : arr) { - numOfZeros += num == 0 ? 1 : 0; + public void duplicateZeros(int[] arr) { + int count = 0; + for (int i = 0; i < arr.length; i++) { + count += arr[i] == 0 ? 1 : 0; + } + int idxOne = arr.length - 1; + int idxTwo = arr.length + count - 1; + while (idxOne != idxTwo) { + insertAtEnd(arr, idxOne, idxTwo--); + if (arr[idxOne] == 0) { + insertAtEnd(arr, idxOne, idxTwo--); + } + idxOne--; + } } - int i = arr.length - 1; - int j = arr.length + numOfZeros - 1; - while (i != j) { - insert(arr, i, j--); - if (arr[i] == 0) { - insert(arr, i, j--); - } - i--; + + private void insertAtEnd(int[] arr, int idxOne, int idxTwo) { + if (idxTwo < arr.length) { + arr[idxTwo] = arr[idxOne]; + } } - } - - private void insert(int[] arr, int i, int j) { - if (j < arr.length) { - arr[j] = arr[i]; - } - } } diff --git a/Easy/Element Appearing More Than 25% In Sorted Array.java b/Easy/Element Appearing More Than 25% In Sorted Array.java index 139c2c07..966f0ce9 100644 --- a/Easy/Element Appearing More Than 25% In Sorted Array.java +++ b/Easy/Element Appearing More Than 25% In Sorted Array.java @@ -1,57 +1,42 @@ class Solution { + + enum Direction {LEFT, RIGHT}; + public int findSpecialInteger(int[] arr) { int n = arr.length; - int oneFourthNum = arr[n / 4]; - int halfNum = arr[n / 2]; - int threeFourthNum = arr[3 * n / 4]; - if(Math.max(n/4, binarySearchRight(arr, 0, n - 1, oneFourthNum)) - - Math.min(n/4, binarySearchLeft(arr, 0, n - 1, oneFourthNum)) >= arr.length / 4) { - return oneFourthNum; - } - if(Math.max(n/2, binarySearchRight(arr, 0, n - 1, halfNum)) - - Math.min(n/2, binarySearchLeft(arr, 0, n - 1, halfNum)) >= arr.length / 4) { - return halfNum; - } - if(Math.max((3 * n)/4, binarySearchRight(arr, 0, n - 1, threeFourthNum)) - - Math.min((3 * n)/4, binarySearchLeft(arr, 0, n - 1, threeFourthNum)) >= arr.length / 4) { - return threeFourthNum; - } - return -1; - } - - private int binarySearchLeft(int[] arr, int start, int end, int num) { - int minIdx = Integer.MAX_VALUE; - while (start < end) { - int mid = (start + end) / 2; - if (arr[mid] == num) { - minIdx = Math.min(mid, minIdx); - end = mid - 1; - } - else if (arr[mid] < num) { - start = mid + 1; - } - else { - end = mid - 1; + if (n == 1) { + return arr[0]; + } + List list = Arrays.asList(arr[n / 4], arr[n / 2], arr[3 * n / 4]); + for (int num : list) { + int firstPosition = getPosition(arr, num, Direction.LEFT); + int lastPosition = getPosition(arr, num, Direction.RIGHT); + if (lastPosition - firstPosition + 1 > n / 4) { + return num; } } - return minIdx; + return -1; } - private int binarySearchRight(int[] arr, int start, int end, int num) { - int maxIdx = Integer.MIN_VALUE; - while (start < end) { - int mid = (start + end) / 2; - if (arr[mid] == num) { - maxIdx = Math.max(mid, maxIdx); - start = mid + 1; - } - else if (arr[mid] < num) { - start = mid + 1; - } - else { - end = mid - 1; + private int getPosition(int[] nums, int num, Direction direction) { + int left = 0; + int right = nums.length - 1; + int idx = -1; + while (left <= right) { + int mid = (left + right) / 2; + if (nums[mid] == num) { + idx = mid; + if (direction == Direction.LEFT) { + right = mid - 1; + } else { + left = mid + 1; + } + } else if (nums[mid] > num) { + right = mid - 1; + } else { + left = mid + 1; } } - return maxIdx; + return idx; } } diff --git a/Easy/Evaluate Boolean Binary Tree.java b/Easy/Evaluate Boolean Binary Tree.java new file mode 100644 index 00000000..39b6edac --- /dev/null +++ b/Easy/Evaluate Boolean Binary Tree.java @@ -0,0 +1,23 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public boolean evaluateTree(TreeNode root) { + if (root.val == 0 || root.val == 1) { + return root.val == 0 ? false : true; + } + return root.val == 2 ? (evaluateTree(root.left) || evaluateTree(root.right)) : (evaluateTree(root.left) && evaluateTree(root.right)); + } +} diff --git a/Easy/Excel Sheet Column Number.java b/Easy/Excel Sheet Column Number.java index dc59608e..44720a07 100644 --- a/Easy/Excel Sheet Column Number.java +++ b/Easy/Excel Sheet Column Number.java @@ -1,10 +1,12 @@ class Solution { - public int titleToNumber(String s) { - int num = 0; - int pow = 0; - for (int i = s.length() - 1; i >= 0; i--) { - num += ((int) Math.pow(26, pow++)) * (s.charAt(i) - 'A' + 1); + public int titleToNumber(String columnTitle) { + int numericValue = 0; + int multiplier = 1; + for (int i = columnTitle.length() - 1; i >= 0; i--) { + int currCharNum = columnTitle.charAt(i) - 'A' + 1; + numericValue += multiplier * currCharNum; + multiplier *= 26; } - return num; + return numericValue; } } diff --git a/Easy/Faulty Keyboard.java b/Easy/Faulty Keyboard.java new file mode 100644 index 00000000..500dc39b --- /dev/null +++ b/Easy/Faulty Keyboard.java @@ -0,0 +1,22 @@ +class Solution { + public String finalString(String s) { + Deque deque = new ArrayDeque<>(); + boolean flip = false; + for (char c : s.toCharArray()) { + if (c == 'i') { + flip = !flip; + } else { + if (flip) { + deque.addFirst(c); + } else { + deque.addLast(c); + } + } + } + StringBuilder sb = new StringBuilder(); + for (char c : deque){ + sb.append(c); + } + return flip ? sb.reverse().toString() : sb.toString(); + } +} diff --git a/Easy/Faulty Sensor.java b/Easy/Faulty Sensor.java new file mode 100644 index 00000000..dabed6c0 --- /dev/null +++ b/Easy/Faulty Sensor.java @@ -0,0 +1,13 @@ +class Solution { + public int badSensor(int[] sensor1, int[] sensor2) { + int idx = 0; + int n = sensor1.length; + while (idx < n && sensor1[idx] == sensor2[idx]) { + idx++; + } + while (idx + 1 < n && sensor1[idx] == sensor2[idx + 1] && sensor1[idx + 1] == sensor2[idx]) { + idx++; + } + return idx >= n - 1 ? -1 : sensor1[idx] == sensor2[idx + 1] ? 1 : 2; + } +} diff --git a/Easy/Fibonacci Number.java b/Easy/Fibonacci Number.java new file mode 100644 index 00000000..dfd1ea21 --- /dev/null +++ b/Easy/Fibonacci Number.java @@ -0,0 +1,14 @@ +class Solution { + public int fib(int n) { + if (n == 0) { + return 0; + } + int[] result = new int[n + 1]; + result[0] = 0; + result[1] = 1; + for (int i = 2; i <= n; i++) { + result[i] = result[i - 1] + result[i - 2]; + } + return result[n]; + } +} diff --git a/Easy/Fibonacci Numbers.java b/Easy/Fibonacci Numbers.java deleted file mode 100644 index f5e33e3b..00000000 --- a/Easy/Fibonacci Numbers.java +++ /dev/null @@ -1,20 +0,0 @@ -class Solution { - public int fib(int N) { - Integer[] memo = new Integer[N + 1]; - return getFib(memo, N); - } - - private int getFib(Integer[] memo, int N) { - if (memo[N] != null) { - return memo[N]; - } - else if (N == 0) { - return 0; - } - else if (N == 1) { - return 1; - } - memo[N] = getFib(memo, N - 1) + getFib(memo, N - 2); - return memo[N]; - } -} diff --git a/Easy/Final Array State After K Multiplication Operations I.java b/Easy/Final Array State After K Multiplication Operations I.java new file mode 100644 index 00000000..da5670de --- /dev/null +++ b/Easy/Final Array State After K Multiplication Operations I.java @@ -0,0 +1,25 @@ +class Solution { + public int[] getFinalState(int[] nums, int k, int multiplier) { + int n = nums.length; + PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt((int[] o) -> o[0]) + .thenComparingInt(o -> o[1])); + for (int i = 0; i < n; i++) { + pq.add(new int[]{nums[i], i}); + } + while (k-- > 0) { + int[] removed = pq.remove(); + int value = removed[0]; + int index = removed[1]; + int newValue = value * multiplier; + pq.add(new int[]{newValue, index}); + } + int[] result = new int[n]; + while (!pq.isEmpty()) { + int[] removed = pq.remove(); + int value = removed[0]; + int index = removed[1]; + result[index] = value; + } + return result; + } +} diff --git a/Easy/Final Value of Variable After Performing Operations.java b/Easy/Final Value of Variable After Performing Operations.java new file mode 100644 index 00000000..1307fdbd --- /dev/null +++ b/Easy/Final Value of Variable After Performing Operations.java @@ -0,0 +1,9 @@ +class Solution { + public int finalValueAfterOperations(String[] operations) { + int x = 0; + for (String op : operations) { + x += op.indexOf('-') != -1 ? -1 : 1; + } + return x; + } +} diff --git a/Easy/Find All Anagrams in a String.java b/Easy/Find All Anagrams in a String.java deleted file mode 100644 index 8d79ab3b..00000000 --- a/Easy/Find All Anagrams in a String.java +++ /dev/null @@ -1,39 +0,0 @@ -class Solution { - public static List findAnagrams(String s, String p) { - List indexes = new ArrayList<>(); - Map pMap = new TreeMap<>(); - - for (char c : p.toCharArray()) { - pMap.put(c, pMap.getOrDefault(c, 0) + 1); - } - - Map map = new TreeMap<>(); - - for (int i=0; i findKDistantIndices(int[] nums, int key, int k) { + List result = new ArrayList<>(); + for (int i = 0; i < nums.length; i++) { + if (nums[i] == key) { + int start = Math.max(result.size() == 0 ? 0 : result.get(result.size() - 1) + 1, i - k); + for (int j = start; j <= i + k && j < nums.length; j++) { + result.add(j); + } + } + } + return result; + } +} diff --git a/Easy/Find All Numbers Disappeared in an Array.java b/Easy/Find All Numbers Disappeared in an Array.java index 4e3865b9..4cab6c67 100644 --- a/Easy/Find All Numbers Disappeared in an Array.java +++ b/Easy/Find All Numbers Disappeared in an Array.java @@ -1,17 +1,17 @@ class Solution { public List findDisappearedNumbers(int[] nums) { + List result = new ArrayList<>(); for (int i = 0; i < nums.length; i++) { - int newIdx = Math.abs(nums[i]) - 1; - if (nums[newIdx] > 0) { - nums[newIdx] *= -1; + int idx = Math.abs(nums[i]) - 1; + if (nums[idx] > 0) { + nums[idx] *= -1; } } - List list = new ArrayList<>(); - for (int i = 1; i <= nums.length; i++) { - if (nums[i - 1] > 0) { - list.add(i); + for (int i = 0; i < nums.length; i++) { + if (nums[i] > 0) { + result.add(i + 1); } } - return list; + return result; } } diff --git a/Easy/Find All the Lonely Nodes.java b/Easy/Find All the Lonely Nodes.java index 369cf65f..1cae56ab 100644 --- a/Easy/Find All the Lonely Nodes.java +++ b/Easy/Find All the Lonely Nodes.java @@ -15,19 +15,26 @@ */ class Solution { public List getLonelyNodes(TreeNode root) { - List list = new ArrayList<>(); - helper(root, null, list); - return list; - } - - private void helper(TreeNode node, TreeNode parent, List list) { - if (node == null) { - return; - } - if (parent != null && ((parent.left != null && parent.right == null) || (parent.right != null && parent.left == null))) { - list.add(node.val); + List lonelyNodes = new ArrayList<>(); + Queue queue = new LinkedList<>(); + queue.add(new TreeNode[]{root, null}); + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + TreeNode[] removed = queue.remove(); + TreeNode node = removed[0]; + TreeNode parent = removed[1]; + if (parent != null && ((parent.left == node && parent.right == null) || (parent.right == node && parent.left == null))) { + lonelyNodes.add(node.val); + } + if (node.left != null) { + queue.add(new TreeNode[]{node.left, node}); + } + if (node.right != null) { + queue.add(new TreeNode[]{node.right, node}); + } + } } - helper(node.left, node, list); - helper(node.right, node, list); + return lonelyNodes; } } diff --git a/Easy/Find Anagram Mappings.java b/Easy/Find Anagram Mappings.java index 74ab5769..3650db78 100644 --- a/Easy/Find Anagram Mappings.java +++ b/Easy/Find Anagram Mappings.java @@ -1,13 +1,13 @@ class Solution { - public int[] anagramMappings(int[] A, int[] B) { - Map map = new HashMap<>(); - for (int i = 0; i < B.length; i++) { - map.put(B[i], i); + public int[] anagramMappings(int[] nums1, int[] nums2) { + Map indexMap = new HashMap<>(); + for (int i = 0; i < nums2.length; i++) { + indexMap.putIfAbsent(nums2[i], i); } - int[] ans = new int[A.length]; - for (int i = 0; i < A.length; i++) { - ans[i] = map.get(A[i]); + int[] result = new int[nums1.length]; + for (int i = 0; i < nums1.length; i++) { + result[i] = indexMap.get(nums1[i]); } - return ans; + return result; } } diff --git a/Easy/Find Champion I.java b/Easy/Find Champion I.java new file mode 100644 index 00000000..4728f452 --- /dev/null +++ b/Easy/Find Champion I.java @@ -0,0 +1,20 @@ +import java.util.Map.Entry; + +class Solution { + public int findChampion(int[][] grid) { + Map map = new HashMap<>(); + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 1) { + map.put(i, map.getOrDefault(i, 0) + 1); + } + } + } + return map.entrySet() + .stream() + .filter(entry -> entry.getValue() == grid.length - 1) + .findFirst() + .map(Entry::getKey) + .orElse(-1); + } +} diff --git a/Easy/Find Closest Number to Zero.java b/Easy/Find Closest Number to Zero.java new file mode 100644 index 00000000..ecb13d9f --- /dev/null +++ b/Easy/Find Closest Number to Zero.java @@ -0,0 +1,17 @@ +class Solution { + public int findClosestNumber(int[] nums) { + int[] result = {Integer.MAX_VALUE, Integer.MIN_VALUE}; + for (int num : nums) { + int distance = Math.abs(num); + if (distance <= result[0]) { + if (distance < result[0]) { + result[0] = distance; + result[1] = num; + } else { + result[1] = Math.max(num, result[1]); + } + } + } + return result[1]; + } +} diff --git a/Easy/Find Closest Person.java b/Easy/Find Closest Person.java new file mode 100644 index 00000000..0d178230 --- /dev/null +++ b/Easy/Find Closest Person.java @@ -0,0 +1,7 @@ +class Solution { + public int findClosest(int x, int y, int z) { + int diffOne = Math.abs(x - z); + int diffTwo = Math.abs(y - z); + return diffOne == diffTwo ? 0 : (diffOne < diffTwo ? 1 : 2); + } +} diff --git a/Easy/Find Common Characters.java b/Easy/Find Common Characters.java index e813b42e..e9fa97e4 100644 --- a/Easy/Find Common Characters.java +++ b/Easy/Find Common Characters.java @@ -1,21 +1,23 @@ class Solution { - public List commonChars(String[] A) { - int[][] counter = new int[A.length][26]; - for (int i = 0; i < A.length; i++) { - for (char c : A[i].toCharArray()) { - counter[i][c - 'a']++; + public List commonChars(String[] words) { + int[] commonFrequency = new int[26]; + Arrays.fill(commonFrequency, Integer.MAX_VALUE); + for (String word : words) { + int[] wordFreq = new int[26]; + for (char c : word.toCharArray()) { + wordFreq[c - 'a']++; + } + for (int i = 0; i < 26; i++) { + commonFrequency[i] = Math.min(commonFrequency[i], wordFreq[i]); } } - List list = new ArrayList<>(); + List result = new ArrayList<>(); for (int i = 0; i < 26; i++) { - int minCount = Integer.MAX_VALUE; - for (int j = 0; j < counter.length; j++) { - minCount = Math.min(minCount, counter[j][i]); - } - while (minCount-- > 0) { - list.add(String.valueOf((char) (97 + i))); + int count = commonFrequency[i]; + while (count-- > 0) { + result.add(String.valueOf((char) (97 + i))); } } - return list; + return result; } } diff --git a/Easy/Find Common Elements Between Two Arrays.java b/Easy/Find Common Elements Between Two Arrays.java new file mode 100644 index 00000000..4a6041ba --- /dev/null +++ b/Easy/Find Common Elements Between Two Arrays.java @@ -0,0 +1,26 @@ +class Solution { + public int[] findIntersectionValues(int[] nums1, int[] nums2) { + Map map1 = buildFrequencyMap(nums1); + Map map2 = buildFrequencyMap(nums2); + int[] result = new int[2]; + for (Integer key : map1.keySet()) { + if (map2.containsKey(key)) { + result[0] += map1.get(key); + } + } + for (Integer key : map2.keySet()) { + if (map1.containsKey(key)) { + result[1] += map2.get(key); + } + } + return result; + } + + private static Map buildFrequencyMap(int[] nums) { + Map map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + return map; + } +} diff --git a/Easy/Find First Palindromic String in the Array.java b/Easy/Find First Palindromic String in the Array.java new file mode 100644 index 00000000..e215ab8d --- /dev/null +++ b/Easy/Find First Palindromic String in the Array.java @@ -0,0 +1,8 @@ +class Solution { + public String firstPalindrome(String[] words) { + return Arrays.stream(words) + .filter(word -> word.equals(new StringBuilder(word).reverse().toString())) + .findFirst() + .orElse(""); + } +} diff --git a/Easy/Find Greatest Common Divisor of Array.java b/Easy/Find Greatest Common Divisor of Array.java new file mode 100644 index 00000000..9e41f8fc --- /dev/null +++ b/Easy/Find Greatest Common Divisor of Array.java @@ -0,0 +1,9 @@ +import java.math.BigInteger; + + +class Solution { + public int findGCD(int[] nums) { + return BigInteger.valueOf(Arrays.stream(nums).max().orElse(1)) + .gcd(BigInteger.valueOf(Arrays.stream(nums).min().orElse(1))).intValue(); + } +} diff --git a/Easy/Find Indices of Stable Mountains.java b/Easy/Find Indices of Stable Mountains.java new file mode 100644 index 00000000..3e0fbd79 --- /dev/null +++ b/Easy/Find Indices of Stable Mountains.java @@ -0,0 +1,11 @@ +class Solution { + public List stableMountains(int[] height, int threshold) { + List result = new ArrayList<>(); + for (int i = 1; i < height.length; i++) { + if (height[i - 1] > threshold) { + result.add(i); + } + } + return result; + } +} diff --git a/Easy/Find Maximum Number of String Pairs.java b/Easy/Find Maximum Number of String Pairs.java new file mode 100644 index 00000000..f2673fbe --- /dev/null +++ b/Easy/Find Maximum Number of String Pairs.java @@ -0,0 +1,13 @@ +class Solution { + public int maximumNumberOfStringPairs(String[] words) { + Set set = new HashSet<>(); + int pairCount = 0; + for (String word : words) { + if (set.contains(new StringBuilder(word).reverse().toString())) { + pairCount++; + } + set.add(word); + } + return pairCount; + } +} diff --git a/Easy/Find Minimum Log Transportation Cost.java b/Easy/Find Minimum Log Transportation Cost.java new file mode 100644 index 00000000..3820474e --- /dev/null +++ b/Easy/Find Minimum Log Transportation Cost.java @@ -0,0 +1,12 @@ +class Solution { + public long minCuttingCost(int n, int m, int k) { + long cost = 0; + if (n > k) { + cost += ((long) (n - k)) * (k); + } + if (m > k) { + cost += ((long) (m - k)) * (k); + } + return cost; + } +} diff --git a/Easy/Find Minimum Operations to Make All Elements Divisible by Three.java b/Easy/Find Minimum Operations to Make All Elements Divisible by Three.java new file mode 100644 index 00000000..c8d6f59e --- /dev/null +++ b/Easy/Find Minimum Operations to Make All Elements Divisible by Three.java @@ -0,0 +1,11 @@ +class Solution { + public int minimumOperations(int[] nums) { + int count = 0; + for (int num : nums) { + if (num % 3 != 0) { + count++; + } + } + return count; + } +} diff --git a/Easy/Find Missing and Repeated Values.java b/Easy/Find Missing and Repeated Values.java new file mode 100644 index 00000000..52cf256e --- /dev/null +++ b/Easy/Find Missing and Repeated Values.java @@ -0,0 +1,21 @@ +class Solution { + public int[] findMissingAndRepeatedValues(int[][] grid) { + int n = grid.length; + int[] frequency = new int[n * n + 1]; + for (int[] row : grid) { + for (int num : row) { + frequency[num]++; + } + } + int[] result = new int[2]; + for (int i = 1; i <= n * n; i++) { + if (frequency[i] == 0) { + result[1] = i; + } + if (frequency[i] == 2) { + result[0] = i; + } + } + return result; + } +} diff --git a/Easy/Find Mode in Binary Search Tree.java b/Easy/Find Mode in Binary Search Tree.java index a803103b..2b1f2fa0 100644 --- a/Easy/Find Mode in Binary Search Tree.java +++ b/Easy/Find Mode in Binary Search Tree.java @@ -14,44 +14,53 @@ * } */ class Solution { - Integer prev = null; - int count = 1; - int max = 0; - public int[] findMode(TreeNode root) { - if (root == null) { - return new int[0]; + public int[] findMode(TreeNode root) { + ResultWrapper resultWrapper = new ResultWrapper(); + inorder(root, resultWrapper); + return resultWrapper.result.stream().mapToInt(Integer::intValue).toArray(); } - List list = new ArrayList<>(); - traverse(root, list); - int[] ans = new int[list.size()]; - for (int i = 0; i < list.size(); i++) { - ans[i] = list.get(i); + + private void inorder(TreeNode node, ResultWrapper resultWrapper) { + if (node == null) { + return; + } + inorder(node.left, resultWrapper); + int val = node.val; + resultWrapper.recordStreak(val); + resultWrapper.updateResult(val); + inorder(node.right, resultWrapper); } - return ans; - } - - private void traverse(TreeNode root, List list) { - if (root == null) { - return; + + private static class ResultWrapper { + private int maxStreak; + private int currStreak; + private Integer curr; + private List result; + + public ResultWrapper() { + this.maxStreak = 0; + this.currStreak = 0; + this.curr = 0; + this.result = new ArrayList<>(); + } + + public void recordStreak(int num) { + if (num == curr) { + currStreak++; + } else { + currStreak = 1; + curr = num; + } + } + + public void updateResult(int num) { + if (currStreak > maxStreak) { + result.clear(); + maxStreak = currStreak; + } + if (currStreak == maxStreak) { + result.add(num); + } + } } - traverse(root.left, list); - if (prev != null) { - if (root.val == prev) { - count++; - } - else { - count = 1; - } - } - if (count > max) { - max = count; - list.clear(); - list.add(root.val); - } - else if (count == max) { - list.add(root.val); - } - prev = root.val; - traverse(root.right, list); - } } diff --git a/Easy/Find N Unique Integers Sum up to Zero.java b/Easy/Find N Unique Integers Sum up to Zero.java index 3eb3d777..1b1de933 100644 --- a/Easy/Find N Unique Integers Sum up to Zero.java +++ b/Easy/Find N Unique Integers Sum up to Zero.java @@ -1,20 +1,17 @@ class Solution { public int[] sumZero(int n) { - int[] arr = new int[n]; + int[] result = new int[n]; int idx = 0; - int num = n / 2; - while (idx < n / 2) { - arr[idx++] = num * -1; - num--; + int half = n / 2; + for (int i = -1 * half; i < 0; i++) { + result[idx++] = i; } if (n % 2 != 0) { - arr[idx++] = 0; + result[idx++] = 0; } - num = n / 2; - while (idx < n) { - arr[idx++] = num; - num--; + for (int i = 1; i <= half; i++) { + result[idx++] = i; } - return arr; + return result; } } diff --git a/Easy/Find Nearest Point That Has the Same X or Y Coordinate.java b/Easy/Find Nearest Point That Has the Same X or Y Coordinate.java new file mode 100644 index 00000000..4a1e5eb4 --- /dev/null +++ b/Easy/Find Nearest Point That Has the Same X or Y Coordinate.java @@ -0,0 +1,34 @@ +class Solution { + public int nearestValidPoint(int x, int y, int[][] points) { + int[] basePoint = new int[]{x, y}; + return IntStream.range(0, points.length).mapToObj(i -> new Point(basePoint, i, points[i])) + .filter( + Point::isMatch) + .sorted(Comparator.comparingInt(Point::getManhattanDistance).thenComparing(Point::getIdx)) + .map(Point::getIdx).findFirst().orElse(-1); + } + + private static class Point { + int[] basePoint; + int idx; + int[] currPoint; + + public Point(int[] basePoint, int idx, int[] currPoint) { + this.basePoint = basePoint; + this.idx = idx; + this.currPoint = currPoint; + } + + public int getIdx() { + return idx; + } + + public int getManhattanDistance() { + return Math.abs(currPoint[0] - basePoint[0]) + Math.abs(currPoint[1] - basePoint[1]); + } + + public boolean isMatch() { + return currPoint[0] == basePoint[0] || currPoint[1] == basePoint[1]; + } + } +} diff --git a/Easy/Find Resultant Array After Removing Anagrams.java b/Easy/Find Resultant Array After Removing Anagrams.java new file mode 100644 index 00000000..c2f0a9b0 --- /dev/null +++ b/Easy/Find Resultant Array After Removing Anagrams.java @@ -0,0 +1,31 @@ +class Solution { + public List removeAnagrams(String[] words) { + List result = new ArrayList<>(); + int startIdx = 0; + for (int i = 1; i < words.length; i++) { + if (!isAnagram(words[i], words[startIdx])) { + result.add(words[startIdx]); + startIdx = i; + } + } + result.add(words[startIdx]); + return result; + } + + private boolean isAnagram(String wordOne, String wordTwo) { + if (wordOne.length() != wordTwo.length()) { + return false; + } + int[] counter = new int[26]; + for (int i = 0; i < wordOne.length(); i++) { + counter[wordOne.charAt(i) - 'a']++; + counter[wordTwo.charAt(i) - 'a']--; + } + for (int i = 0; i < 26; i++) { + if (counter[i] != 0) { + return false; + } + } + return true; + } +} diff --git a/Easy/Find Smallest Letter Greater Than Target.java b/Easy/Find Smallest Letter Greater Than Target.java index 161760cb..6cdfb73a 100644 --- a/Easy/Find Smallest Letter Greater Than Target.java +++ b/Easy/Find Smallest Letter Greater Than Target.java @@ -1,24 +1,17 @@ class Solution { - public char nextGreatestLetter(char[] letters, char target) { - int start = 0; - int end = letters.length - 1; - // ASCII char greater than 'z' - char smallestChar = '{'; - while (start <= end) { - int mid = (start + end) / 2; - if (letters[mid] - target > 0) { - if (smallestChar - letters[mid] > 0) { - smallestChar = letters[mid]; + public char nextGreatestLetter(char[] letters, char target) { + int start = 0; + int end = letters.length - 1; + int idx = -1; + while (start <= end) { + int mid = (start + end) / 2; + if (letters[mid] > target) { + idx = mid; + end = mid - 1; + } else { + start = mid + 1; + } } - end = mid - 1; - } - else if (letters[mid] - target == 0) { - start = mid + 1; - } - else { - start = mid + 1; - } + return idx == -1 ? letters[0] : letters[idx]; } - return smallestChar == '{' ? letters[0] : smallestChar; - } } diff --git a/Easy/Find Subarrays With Equal Sum.java b/Easy/Find Subarrays With Equal Sum.java new file mode 100644 index 00000000..834989a0 --- /dev/null +++ b/Easy/Find Subarrays With Equal Sum.java @@ -0,0 +1,13 @@ +class Solution { + public boolean findSubarrays(int[] nums) { + Set set = new HashSet<>(); + for (int i = 0; i < nums.length - 1; i++) { + int sum = nums[i] + nums[i + 1]; + if (set.contains(sum)) { + return true; + } + set.add(sum); + } + return false; + } +} diff --git a/Easy/Find Target Indices After Sorting Array.java b/Easy/Find Target Indices After Sorting Array.java new file mode 100644 index 00000000..d000c8ad --- /dev/null +++ b/Easy/Find Target Indices After Sorting Array.java @@ -0,0 +1,15 @@ +class Solution { + public List targetIndices(int[] nums, int target) { + int count = 0; + int lessThanCount = 0; + for (int num : nums) { + count += num == target ? 1 : 0; + lessThanCount += num < target ? 1 : 0; + } + List result = new ArrayList<>(); + while (count-- > 0) { + result.add(lessThanCount++); + } + return result; + } +} diff --git a/Easy/Find Words Containing Character.java b/Easy/Find Words Containing Character.java new file mode 100644 index 00000000..ba268c41 --- /dev/null +++ b/Easy/Find Words Containing Character.java @@ -0,0 +1,8 @@ +class Solution { + public List findWordsContaining(String[] words, char x) { + return IntStream.range(0, words.length) + .filter(i -> words[i].indexOf(x) != -1) + .boxed() + .collect(Collectors.toList()); + } +} diff --git a/Easy/Find Words That Can Be Formed by Characters.java b/Easy/Find Words That Can Be Formed by Characters.java index 46d11d0f..23550740 100644 --- a/Easy/Find Words That Can Be Formed by Characters.java +++ b/Easy/Find Words That Can Be Formed by Characters.java @@ -1,29 +1,24 @@ class Solution { - public int countCharacters(String[] words, String chars) { - Map charFreq = getMap(chars); - int length = 0; - for (String word : words) { - if (canBeFormed(charFreq, getMap(word))) { - length += word.length(); - } + public int countCharacters(String[] words, String chars) { + Map targetMap = buildFrequencyMap(chars); + return Arrays.stream(words) + .filter(word -> doesIntersect(buildFrequencyMap(word), targetMap)) + .mapToInt(String::length) + .sum(); } - return length; - } - - private Map getMap(String s) { - Map map = new HashMap<>(); - for (char c : s.toCharArray()) { - map.put(c, map.getOrDefault(c, 0) + 1); + + private static boolean doesIntersect(Map currMap, Map targetMap) { + for (Character key : currMap.keySet()) { + if (targetMap.getOrDefault(key, 0L) < currMap.get(key)) { + return false; + } + } + return true; } - return map; - } - - private boolean canBeFormed(Map main, Map toBeChecked) { - for (Character key : toBeChecked.keySet()) { - if (main.getOrDefault(key, 0) < toBeChecked.get(key)) { - return false; - } + + private static Map buildFrequencyMap(String s) { + return s.chars() + .mapToObj(c -> (char) c) + .collect(Collectors.groupingBy(Function.identity(), HashMap::new, Collectors.counting())); } - return true; - } } diff --git a/Easy/Find if Digit Game Can Be Won.java b/Easy/Find if Digit Game Can Be Won.java new file mode 100644 index 00000000..22c76892 --- /dev/null +++ b/Easy/Find if Digit Game Can Be Won.java @@ -0,0 +1,14 @@ +class Solution { + public boolean canAliceWin(int[] nums) { + int singleDigitSum = 0; + int doubleDigitSum = 0; + for (int num : nums) { + if (String.valueOf(num).length() > 1) { + doubleDigitSum += num; + } else { + singleDigitSum += num; + } + } + return singleDigitSum > doubleDigitSum || doubleDigitSum > singleDigitSum; + } +} diff --git a/Easy/Find if Path Exists in Graph.java b/Easy/Find if Path Exists in Graph.java new file mode 100644 index 00000000..7a0c6a47 --- /dev/null +++ b/Easy/Find if Path Exists in Graph.java @@ -0,0 +1,26 @@ +class Solution { + public boolean validPath(int n, int[][] edges, int source, int destination) { + Map> graph = new HashMap<>(); + for (int[] edge : edges) { + graph.computeIfAbsent(edge[0], k -> new ArrayList<>()).add(edge[1]); + graph.computeIfAbsent(edge[1], k -> new ArrayList<>()).add(edge[0]); + } + Queue queue = new LinkedList<>(); + queue.add(source); + Set visited = new HashSet<>(); + visited.add(source); + while (!queue.isEmpty()) { + Integer removed = queue.remove(); + if (removed == destination) { + return true; + } + for (Integer connection : graph.getOrDefault(removed, new ArrayList<>())) { + if (!visited.contains(connection)) { + queue.add(connection); + visited.add(connection); + } + } + } + return false; + } +} diff --git a/Easy/Find the Array Concatenation Value.java b/Easy/Find the Array Concatenation Value.java new file mode 100644 index 00000000..974ca82b --- /dev/null +++ b/Easy/Find the Array Concatenation Value.java @@ -0,0 +1,13 @@ +class Solution { + public long findTheArrayConcVal(int[] nums) { + long concatenatedValue = 0; + int start = 0; + int end = nums.length - 1; + while (start <= end) { + concatenatedValue += start == end ? nums[start] : Integer.parseInt(nums[start] + "" + nums[end]); + start++; + end--; + } + return concatenatedValue; + } +} diff --git a/Easy/Find the Child Who Has the Ball After K Seconds.java b/Easy/Find the Child Who Has the Ball After K Seconds.java new file mode 100644 index 00000000..6a4c8193 --- /dev/null +++ b/Easy/Find the Child Who Has the Ball After K Seconds.java @@ -0,0 +1,7 @@ +class Solution { + public int numberOfChild(int n, int k) { + int factor = k / (n - 1); + int remainder = k % (n - 1); + return factor % 2 == 0 ? remainder : n - 1 - remainder; + } +} diff --git a/Easy/Find the Difference of Two Arrays.java b/Easy/Find the Difference of Two Arrays.java new file mode 100644 index 00000000..fa061f5f --- /dev/null +++ b/Easy/Find the Difference of Two Arrays.java @@ -0,0 +1,9 @@ +class Solution { + public List> findDifference(int[] nums1, int[] nums2) { + Set setOne = Arrays.stream(nums1).boxed().collect(Collectors.toSet()); + Set setTwo = Arrays.stream(nums2).boxed().collect(Collectors.toSet()); + return Arrays.asList( + setOne.stream().filter(e -> !setTwo.contains(e)).collect(Collectors.toList()), + setTwo.stream().filter(e -> !setOne.contains(e)).collect(Collectors.toList())); + } +} diff --git a/Easy/Find the Distance Value Between Two Arrays.java b/Easy/Find the Distance Value Between Two Arrays.java index 69df4f37..0fb09098 100644 --- a/Easy/Find the Distance Value Between Two Arrays.java +++ b/Easy/Find the Distance Value Between Two Arrays.java @@ -1,18 +1,28 @@ class Solution { public int findTheDistanceValue(int[] arr1, int[] arr2, int d) { - TreeSet set = new TreeSet<>(); - for (int num : arr2) { - set.add(num); + Arrays.sort(arr2); + int distance = 0; + for (int i = 0; i < arr1.length; i++) { + if (outsideRange(arr2, arr1[i] - d, arr1[i] + d)) { + distance++; + } } - int count = 0; - for (int num : arr1) { - Integer higher = set.ceiling(num); - Integer lower = set.floor(num); - if ((higher != null && Math.abs(higher - num) <= d) || (lower != null && Math.abs(lower - num) <= d)) { - continue; + return distance; + } + + private static boolean outsideRange(int[] arr, int from, int to) { + int start = 0; + int end = arr.length - 1; + while (start <= end) { + int mid = start + (end - start) / 2; + if (arr[mid] >= from && arr[mid] <= to) { + return false; + } else if (arr[mid] < from) { + start = mid + 1; + } else { + end = mid - 1; } - count++; } - return count; + return true; } } diff --git a/Easy/Find the Distinct Difference Array.java b/Easy/Find the Distinct Difference Array.java new file mode 100644 index 00000000..5578427f --- /dev/null +++ b/Easy/Find the Distinct Difference Array.java @@ -0,0 +1,17 @@ +class Solution { + public int[] distinctDifferenceArray(int[] nums) { + int[] rightToLeft = new int[nums.length]; + Set set = new HashSet<>(); + for (int i = nums.length - 1; i >= 0; i--) { + set.add(nums[i]); + rightToLeft[i] = set.size(); + } + int[] diff = new int[nums.length]; + set.clear(); + for (int i = 0; i < nums.length; i++) { + set.add(nums[i]); + diff[i] = set.size() - (i == nums.length - 1 ? 0 : rightToLeft[i + 1]); + } + return diff; + } +} diff --git a/Easy/Find the Highest Altitude.java b/Easy/Find the Highest Altitude.java new file mode 100644 index 00000000..aa7d12e5 --- /dev/null +++ b/Easy/Find the Highest Altitude.java @@ -0,0 +1,11 @@ +class Solution { + public int largestAltitude(int[] gain) { + int highestAltitude = 0; + int currAltitude = 0; + for (int i = 0; i < gain.length; i++) { + currAltitude = currAltitude + gain[i]; + highestAltitude = Math.max(highestAltitude, currAltitude); + } + return highestAltitude; + } +} diff --git a/Easy/Find the Integer Added to Array I.java b/Easy/Find the Integer Added to Array I.java new file mode 100644 index 00000000..c5d551e3 --- /dev/null +++ b/Easy/Find the Integer Added to Array I.java @@ -0,0 +1,11 @@ +class Solution { + public int addedInteger(int[] nums1, int[] nums2) { + int minOne = nums1[0]; + int minTwo = nums2[0]; + for (int i = 0; i < nums1.length; i++) { + minOne = Math.min(minOne, nums1[i]); + minTwo = Math.min(minTwo, nums2[i]); + } + return minTwo - minOne; + } +} diff --git a/Easy/Find the K-Beauty of a Number.java b/Easy/Find the K-Beauty of a Number.java new file mode 100644 index 00000000..a2a1b9f6 --- /dev/null +++ b/Easy/Find the K-Beauty of a Number.java @@ -0,0 +1,13 @@ +class Solution { + public int divisorSubstrings(int num, int k) { + String numString = String.valueOf(num); + int count = 0; + for (int i = 0; i <= numString.length() - k; i++) { + int substringNum = Integer.parseInt(numString.substring(i, i + k)); + if (substringNum != 0 && num % substringNum == 0) { + count++; + } + } + return count; + } +} diff --git a/Easy/Find the K-or of an Array.java b/Easy/Find the K-or of an Array.java new file mode 100644 index 00000000..48343d5e --- /dev/null +++ b/Easy/Find the K-or of an Array.java @@ -0,0 +1,31 @@ +class Solution { + public int findKOr(int[] nums, int k) { + Map map = new HashMap<>(); + for (int num : nums) { + List setBits = getSetBits(num); + for (Integer setBit : setBits) { + map.put(setBit, map.getOrDefault(setBit, 0) + 1); + } + } + int result = 0; + for (int i = 0, p = 1; i < 32; i++, p *= 2) { + if (map.getOrDefault(i, 0) >= k) { + result += p; + } + } + return result; + } + + private static List getSetBits(int num) { + List bits = new ArrayList<>(); + int bit = 0; + while (num > 0) { + if (num % 2 == 1) { + bits.add(bit); + } + num = num / 2; + bit++; + } + return bits; + } +} diff --git a/Easy/Find the Longest Balanced Substring of a Binary String.java b/Easy/Find the Longest Balanced Substring of a Binary String.java new file mode 100644 index 00000000..2b1d3f2a --- /dev/null +++ b/Easy/Find the Longest Balanced Substring of a Binary String.java @@ -0,0 +1,25 @@ +class Solution { + public int findTheLongestBalancedSubstring(String s) { + int maxLength = 0; + int idx = 0; + while (idx < s.length()) { + if (s.charAt(idx) != '0') { + idx++; + continue; + } + int zeroCount = 0; + while (idx < s.length() && s.charAt(idx) == '0') { + idx++; + zeroCount++; + } + int oneCount = 0; + while (idx < s.length() && s.charAt(idx) == '1') { + idx++; + oneCount++; + } + maxLength = Math.max(maxLength, 2 * Math.min(zeroCount, oneCount)); + + } + return maxLength; + } +} diff --git a/Easy/Find the Losers of the Circular Game.java b/Easy/Find the Losers of the Circular Game.java new file mode 100644 index 00000000..aaa8c059 --- /dev/null +++ b/Easy/Find the Losers of the Circular Game.java @@ -0,0 +1,19 @@ +class Solution { + public int[] circularGameLosers(int n, int k) { + Set set = new HashSet<>(); + int player = 1; + int multiple = k; + while (set.add(player)) { + player = (player + k) % n; + player = player == 0 ? n : player; + k += multiple; + } + int[] result = new int[n - set.size()]; + for (int i = 1, j = 0; i <= n; i++) { + if (!set.contains(i)) { + result[j++] = i; + } + } + return result; + } +} diff --git a/Easy/Find the Maximum Achievable Number.java b/Easy/Find the Maximum Achievable Number.java new file mode 100644 index 00000000..841862be --- /dev/null +++ b/Easy/Find the Maximum Achievable Number.java @@ -0,0 +1,5 @@ +class Solution { + public int theMaximumAchievableX(int num, int t) { + return num + 2 * t; + } +} diff --git a/Easy/Find the Middle Index in Array.java b/Easy/Find the Middle Index in Array.java new file mode 100644 index 00000000..4ad9ddbf --- /dev/null +++ b/Easy/Find the Middle Index in Array.java @@ -0,0 +1,20 @@ +class Solution { + public int findMiddleIndex(int[] nums) { + int n = nums.length; + int[] rightSum = new int[n]; + int currSum = 0; + for (int i = n - 1; i >= 0; i--) { + currSum += nums[i]; + rightSum[i] = currSum; + } + currSum = 0; + for (int i = 0; i < n; i++) { + int rightCurrSum = i != n - 1 ? rightSum[i + 1] : 0; + if (currSum == rightCurrSum) { + return i; + } + currSum += nums[i]; + } + return -1; + } +} diff --git a/Easy/Find the Number of Good Pairs I.java b/Easy/Find the Number of Good Pairs I.java new file mode 100644 index 00000000..143d6abd --- /dev/null +++ b/Easy/Find the Number of Good Pairs I.java @@ -0,0 +1,13 @@ +class Solution { + public int numberOfPairs(int[] nums1, int[] nums2, int k) { + int count = 0; + for (int i = 0; i < nums1.length; i++) { + for (int j = 0; j < nums2.length; j++) { + if (nums1[i] % (nums2[j] * k) == 0) { + count++; + } + } + } + return count; + } +} diff --git a/Easy/Find the Number of Winning Players.java b/Easy/Find the Number of Winning Players.java new file mode 100644 index 00000000..fd4ea2ba --- /dev/null +++ b/Easy/Find the Number of Winning Players.java @@ -0,0 +1,14 @@ +class Solution { + public int winningPlayerCount(int n, int[][] pick) { + Map> map = new HashMap<>(); + Set winners = new HashSet<>(); + for (int[] p : pick) { + map.computeIfAbsent(p[0], k -> new HashMap<>()); + map.get(p[0]).put(p[1], map.get(p[0]).getOrDefault(p[1], 0) + 1); + if (map.get(p[0]).get(p[1]) > p[0]) { + winners.add(p[0]); + } + } + return winners.size(); + } +} diff --git a/Easy/Find the Original Typed String I.java b/Easy/Find the Original Typed String I.java new file mode 100644 index 00000000..dd6a5177 --- /dev/null +++ b/Easy/Find the Original Typed String I.java @@ -0,0 +1,17 @@ +class Solution { + public int possibleStringCount(String word) { + int idx = 0; + int result = 1; + while (idx < word.length()) { + int currIdx = idx; + char c = word.charAt(currIdx); + while (currIdx < word.length() && word.charAt(currIdx) == c) { + currIdx++; + } + int segement = currIdx - idx; + result += segement - 1; + idx = currIdx; + } + return result; + } +} diff --git a/Easy/Find the Peaks.java b/Easy/Find the Peaks.java new file mode 100644 index 00000000..f6120cd5 --- /dev/null +++ b/Easy/Find the Peaks.java @@ -0,0 +1,11 @@ +class Solution { + public List findPeaks(int[] mountain) { + List result = new ArrayList<>(); + for (int i = 1; i < mountain.length - 1; i++) { + if (mountain[i] > mountain[i - 1] && mountain[i] > mountain[i + 1]) { + result.add(i); + } + } + return result; + } +} diff --git a/Easy/Find the Pivot Integer.java b/Easy/Find the Pivot Integer.java new file mode 100644 index 00000000..3cad5e0b --- /dev/null +++ b/Easy/Find the Pivot Integer.java @@ -0,0 +1,18 @@ +class Solution { + public int pivotInteger(int n) { + int[] leftToRightSum = new int[n]; + int currSum = 0; + for (int i = 0; i < n; i++) { + currSum += i + 1; + leftToRightSum[i] = currSum; + } + int rightToLeftSum = 0; + for (int i = n - 1; i >= 0; i--) { + rightToLeftSum += i + 1; + if (leftToRightSum[i] == rightToLeftSum) { + return i + 1; + } + } + return -1; + } +} diff --git a/Easy/Find the Power of K-Size Subarrays I.java b/Easy/Find the Power of K-Size Subarrays I.java new file mode 100644 index 00000000..975c1a3a --- /dev/null +++ b/Easy/Find the Power of K-Size Subarrays I.java @@ -0,0 +1,18 @@ +class Solution { + public int[] resultsArray(int[] nums, int k) { + if (k == 1) { + return nums; + } + int n = nums.length; + int[] result = new int[n - k + 1]; + Arrays.fill(result, -1); + int count = 1; + for (int i = 0; i < nums.length - 1; i++) { + count = (nums[i + 1] - nums[i] == 1) ? count + 1 : 1; + if (count >= k) { + result[i - k + 2] = nums[i + 1]; + } + } + return result; + } +} diff --git a/Easy/Find the Sum of Encrypted Integers.java b/Easy/Find the Sum of Encrypted Integers.java new file mode 100644 index 00000000..6cee31bc --- /dev/null +++ b/Easy/Find the Sum of Encrypted Integers.java @@ -0,0 +1,21 @@ +class Solution { + public int sumOfEncryptedInt(int[] nums) { + int sum = 0; + for (int num : nums) { + sum += getEncryptedSum(num); + } + return sum; + } + + private static int getEncryptedSum(int num) { + int count = 0; + int max = 0; + while (num > 0) { + int digit = num % 10; + num /= 10; + count++; + max = Math.max(digit, max); + } + return Integer.parseInt(String.join("", Collections.nCopies(count, String.valueOf(max)))); + } +} diff --git a/Easy/Find the Town Judge.java b/Easy/Find the Town Judge.java index 60c4a84f..8605e848 100644 --- a/Easy/Find the Town Judge.java +++ b/Easy/Find the Town Judge.java @@ -1,18 +1,15 @@ class Solution { - public int findJudge(int N, int[][] trust) { - int[] count = new int[N + 1]; - - for (int[] item : trust) { - count[item[0]]--; - count[item[1]]++; - } - - for (int i = 1; i <= N; i++) { - if (count[i] == N - 1) { - return i; - } - } - - return -1; + public int findJudge(int n, int[][] trust) { + int[] trustScore = new int[n + 1]; + for (int[] trustPair : trust) { + trustScore[trustPair[1]]++; + trustScore[trustPair[0]]--; } + for (int i = 1; i <= n; i++) { + if (trustScore[i] == n - 1) { + return i; + } + } + return -1; + } } diff --git a/Easy/Find the Width of Columns of a Grid.java b/Easy/Find the Width of Columns of a Grid.java new file mode 100644 index 00000000..843813b9 --- /dev/null +++ b/Easy/Find the Width of Columns of a Grid.java @@ -0,0 +1,13 @@ +class Solution { + public int[] findColumnWidth(int[][] grid) { + int[] result = new int[grid[0].length]; + for (int i = 0; i < grid[0].length; i++) { + int maxLength = 0; + for (int j = 0; j < grid.length; j++) { + maxLength = Math.max(maxLength, String.valueOf(grid[j][i]).length()); + } + result[i] = maxLength; + } + return result; + } +} diff --git a/Easy/Find the XOR of Numbers Which Appear Twice.java b/Easy/Find the XOR of Numbers Which Appear Twice.java new file mode 100644 index 00000000..baa845bc --- /dev/null +++ b/Easy/Find the XOR of Numbers Which Appear Twice.java @@ -0,0 +1,12 @@ +class Solution { + public int duplicateNumbersXOR(int[] nums) { + Set set = new HashSet<>(); + int xor = 0; + for (int num : nums) { + if (!set.add(num)) { + xor = xor ^ num; + } + } + return xor; + } +} diff --git a/Easy/Find the difference.java b/Easy/Find the difference.java index 710a70d3..ca12be6d 100644 --- a/Easy/Find the difference.java +++ b/Easy/Find the difference.java @@ -1,15 +1,15 @@ class Solution { - public char findTheDifference(String s, String t) { - int[] counter = new int[26]; - for (char c : s.toCharArray()) { - counter[c - 'a']++; + public char findTheDifference(String s, String t) { + int[] frequency = new int[26]; + for (char c : s.toCharArray()) { + frequency[c - 'a']++; + } + for (char c : t.toCharArray()) { + if (frequency[c - 'a'] == 0) { + return c; + } + frequency[c - 'a']--; + } + return ' '; } - for (char c : t.toCharArray()) { - if (counter[c - 'a'] == 0) { - return c; - } - counter[c - 'a']--; - } - return '-'; - } } diff --git a/Easy/Finding 3-Digit Even Numbers.java b/Easy/Finding 3-Digit Even Numbers.java new file mode 100644 index 00000000..e8feb4aa --- /dev/null +++ b/Easy/Finding 3-Digit Even Numbers.java @@ -0,0 +1,33 @@ +class Solution { + public int[] findEvenNumbers(int[] digits) { + List list = new ArrayList<>(); + int[] counter = new int[10]; + for (int digit : digits) { + counter[digit]++; + } + for (int digitOne = 1; digitOne <= 9; digitOne++) { + if (counter[digitOne] > 0) { + counter[digitOne]--; + for (int digitTwo = 0; digitTwo <= 9; digitTwo++) { + if (counter[digitTwo] > 0) { + counter[digitTwo]--; + for (int digitThree = 0; digitThree <= 8; digitThree += 2) { + if (counter[digitThree] > 0) { + list.add(digitOne * 100 + digitTwo * 10 + digitThree); + } + } + counter[digitTwo]++; + } + } + counter[digitOne]++; + } + } + int[] result = new int[list.size()]; + int idx = 0; + for (int num : list) { + result[idx++] = num; + } + Arrays.sort(result); + return result; + } +} diff --git a/Easy/First Letter to Appear Twice.java b/Easy/First Letter to Appear Twice.java new file mode 100644 index 00000000..23a3f653 --- /dev/null +++ b/Easy/First Letter to Appear Twice.java @@ -0,0 +1,12 @@ +class Solution { + public char repeatedCharacter(String s) { + boolean[] seen = new boolean[26]; + for (char c : s.toCharArray()) { + if (seen[c - 'a']) { + return c; + } + seen[c - 'a'] = true; + } + return ' '; + } +} diff --git a/Easy/First Unique Character in a String.java b/Easy/First Unique Character in a String.java index 64bacbda..1659cbb5 100644 --- a/Easy/First Unique Character in a String.java +++ b/Easy/First Unique Character in a String.java @@ -1,16 +1,11 @@ class Solution { public int firstUniqChar(String s) { - int[] arr = new int[26]; + int[] count = new int[26]; for (char c : s.toCharArray()) { - if (arr[c - 'a'] != 0) { - arr[c - 'a'] = -1; - } - else { - arr[c - 'a'] = 1; - } + count[c - 'a']++; } for (int i = 0; i < s.length(); i++) { - if (arr[s.charAt(i) - 'a'] == 1) { + if (count[s.charAt(i) - 'a'] == 1) { return i; } } diff --git a/Easy/Fizz Buzz.java b/Easy/Fizz Buzz.java index 73fa230f..c28fabc9 100644 --- a/Easy/Fizz Buzz.java +++ b/Easy/Fizz Buzz.java @@ -1,11 +1,17 @@ class Solution { public List fizzBuzz(int n) { - return IntStream.range(1, n + 1) - .boxed() - .map(e -> ( - e % 3 == 0 && e % 5 == 0 ? "FizzBuzz" - : (e % 3 == 0 ? "Fizz" : (e % 5 == 0 ? "Buzz" : String.valueOf(e))) - ) - ).collect(Collectors.toList()); - } + List result = new ArrayList<>(); + for (int i = 1; i <= n; i++) { + if (i % 15 == 0) { + result.add("FizzBuzz"); + } else if (i % 3 == 0) { + result.add("Fizz"); + } else if (i % 5 == 0) { + result.add("Buzz"); + } else { + result.add(String.valueOf(i)); + } + } + return result; + } } diff --git a/Easy/Flip Game.java b/Easy/Flip Game.java index 727227e2..097acf18 100644 --- a/Easy/Flip Game.java +++ b/Easy/Flip Game.java @@ -1,30 +1,11 @@ class Solution { - public static List generatePossibleNextMoves(String s) { - List ans = new ArrayList<>(); - - if (s.length() < 2) { - return ans; - } - - if (s.equals("--")) { - return ans; - } - - int i = 0; - while (i < s.length()-1) { - if (s.charAt(i) == s.charAt(i+1) && s.charAt(i) == '+') { - StringBuilder sb = new StringBuilder(); - sb.append(s.substring(0, i)); - sb.append('-'); - sb.append('-'); - sb.append(s.substring(i+2)); - - ans.add(sb.toString()); + public List generatePossibleNextMoves(String currentState) { + List moves = new ArrayList<>(); + for (int i = 0; i < currentState.length() - 1; i++) { + if (currentState.substring(i, i + 2).equals("++")) { + moves.add(currentState.substring(0, i) + "--" + currentState.substring(i + 2)); } - - i++; } - - return ans; + return moves; } } diff --git a/Easy/Flipping an Image.java b/Easy/Flipping an Image.java index 8c4a0813..0e5d44f3 100644 --- a/Easy/Flipping an Image.java +++ b/Easy/Flipping an Image.java @@ -1,17 +1,14 @@ class Solution { public int[][] flipAndInvertImage(int[][] A) { - for (int[] arr : A) { - int start = 0; - int end = arr.length - 1; - while (start < end) { - int temp = arr[start]; - arr[start++] = arr[end]; - arr[end--] = temp; - } - } - for (int[] arr : A) { - for (int i = 0; i < arr.length; i++) { - arr[i] = arr[i] == 1 ? 0 : 1; + int numRows = A.length; + int numCols = A[0].length - 1; + for (int rowIdx = 0; rowIdx < numRows; rowIdx++) { + int startIdx = 0; + int endIdx = numCols; + while (startIdx <= endIdx) { + int temp = A[rowIdx][startIdx]; + A[rowIdx][startIdx++] = A[rowIdx][endIdx] == 1 ? 0 : 1; + A[rowIdx][endIdx--] = temp == 1 ? 0 : 1; } } return A; diff --git a/Easy/Flood Fill.java b/Easy/Flood Fill.java index 38cb718e..e3806b21 100644 --- a/Easy/Flood Fill.java +++ b/Easy/Flood Fill.java @@ -1,20 +1,31 @@ class Solution { - public int[][] dirs = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; - public int[][] floodFill(int[][] image, int sr, int sc, int newColor) { - dfs(image, sr, sc, newColor, image[sr][sc]); - return image; + private static final int[][] DIRS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; + + public int[][] floodFill(int[][] image, int sr, int sc, int newColor) { + int numOfRows = image.length; + int numOfCols = image[0].length; + int originalColor = image[sr][sc]; + if (newColor == originalColor) { + return image; } - - private void dfs(int[][] image, int x, int y, int newColor, int oldColor) { - if(x < 0 || x >= image.length || y < 0 || y >= image[0].length || image[x][y] == newColor) { - return; - } - - if (image[x][y] == oldColor) { - image[x][y] = newColor; - for (int[] dir : dirs) { - dfs(image, x + dir[0], y + dir[1], newColor, oldColor); - } + Queue queue = new LinkedList<>(); + queue.add(new int[]{sr, sc}); + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + int[] coordinate = queue.remove(); + int xPoint = coordinate[0]; + int yPoint = coordinate[1]; + image[xPoint][yPoint] = newColor; + for (int[] dir : DIRS) { + int newXPoint = xPoint + dir[0]; + int newYPoint = yPoint + dir[1]; + if (newXPoint >= 0 && newYPoint >= 0 && newXPoint < numOfRows && newYPoint < numOfCols && image[newXPoint][newYPoint] == originalColor) { + queue.add(new int[]{newXPoint, newYPoint}); + } } + } } + return image; + } } diff --git a/Easy/Flower Planting With No Adjacent.java b/Easy/Flower Planting With No Adjacent.java index 70ea74de..88bf6a8b 100644 --- a/Easy/Flower Planting With No Adjacent.java +++ b/Easy/Flower Planting With No Adjacent.java @@ -1,25 +1,22 @@ class Solution { - public int[] gardenNoAdj(int N, int[][] paths) { - Map> map = new HashMap<>(); + public int[] gardenNoAdj(int n, int[][] paths) { + Map> map = new HashMap<>(); for (int[] path : paths) { - map.computeIfAbsent(path[0], k -> new ArrayList<>()).add(path[1]); - map.computeIfAbsent(path[1], k -> new ArrayList<>()).add(path[0]); + map.computeIfAbsent(path[0], k -> new HashSet<>()).add(path[1]); + map.computeIfAbsent(path[1], k -> new HashSet<>()).add(path[0]); } - int[] ans = new int[N]; - for (int i = 0; i < N; i++) { - Set neighbourPlant = new HashSet<>(); - for (Integer neighbour : map.getOrDefault(i + 1, new ArrayList<>())) { - if (ans[neighbour - 1] != 0) { - neighbourPlant.add(ans[neighbour - 1]); - } - } - for (int j = 1; j <= 4; j++) { - if (!neighbourPlant.contains(j)) { - ans[i] = j; - break; + int[] result = new int[n]; + for (int i = 1; i <= n; i++) { + int[] colors = new int[5]; + for (int neighbor : map.getOrDefault(i, new HashSet<>())) { + colors[result[neighbor - 1]] = 1; + } + for (int c = 4; c > 0; c--) { + if (colors[c] != 1) { + result[i - 1] = c; } } } - return ans; + return result; } } diff --git a/Easy/Form Smallest Number From Two Digit Arrays.java b/Easy/Form Smallest Number From Two Digit Arrays.java new file mode 100644 index 00000000..5ae6bd94 --- /dev/null +++ b/Easy/Form Smallest Number From Two Digit Arrays.java @@ -0,0 +1,21 @@ +class Solution { + public int minNumber(int[] nums1, int[] nums2) { + int[] counter = new int[10]; + int smallestOne = nums1[0]; + int smallestTwo = nums2[0]; + for (int num : nums1) { + counter[num]++; + smallestOne = Math.min(smallestOne, num); + } + for (int num : nums2) { + counter[num]++; + smallestTwo = Math.min(smallestTwo, num); + } + for (int i = 1; i < counter.length; i++) { + if (counter[i] == 2) { + return i; + } + } + return Math.min(smallestOne, smallestTwo) * 10 + Math.max(smallestOne, smallestTwo); + } +} diff --git a/Easy/Fruits Into Baskets II.java b/Easy/Fruits Into Baskets II.java new file mode 100644 index 00000000..e0afa848 --- /dev/null +++ b/Easy/Fruits Into Baskets II.java @@ -0,0 +1,20 @@ +class Solution { + public int numOfUnplacedFruits(int[] fruits, int[] baskets) { + int count = 0; + for (int fruit : fruits) { + int idx = -1; + for (int i = 0; i < baskets.length; i++) { + if (baskets[i] >= fruit) { + idx = i; + break; + } + } + if (idx == -1) { + count++; + } else { + baskets[idx] = -1; + } + } + return count; + } +} diff --git a/Easy/Furthest Point From Origin.java b/Easy/Furthest Point From Origin.java new file mode 100644 index 00000000..d7abca92 --- /dev/null +++ b/Easy/Furthest Point From Origin.java @@ -0,0 +1,14 @@ +class Solution { + public int furthestDistanceFromOrigin(String moves) { + int emptyCount = 0; + int direction = 0; + for (char c : moves.toCharArray()) { + if (c == '_') { + emptyCount++; + } else { + direction += c == 'L' ? -1 : 1; + } + } + return Math.abs(direction) + emptyCount; + } +} diff --git a/Easy/Get Maximum in Generated Array.java b/Easy/Get Maximum in Generated Array.java new file mode 100644 index 00000000..58ae1efe --- /dev/null +++ b/Easy/Get Maximum in Generated Array.java @@ -0,0 +1,20 @@ +class Solution { + public int getMaximumGenerated(int n) { + if (n == 0) { + return 0; + } + int[] nums = new int[n + 1]; + nums[0] = 0; + nums[1] = 1; + int max = 1; + for (int i = 2; i <= n; i++) { + if (i % 2 == 0) { + nums[i] = nums[i / 2]; + } else { + nums[i] = nums[i / 2] + nums[i / 2 + 1]; + } + max = Math.max(nums[i], max); + } + return max; + } +} diff --git a/Easy/Goal Parser Interpretation.java b/Easy/Goal Parser Interpretation.java new file mode 100644 index 00000000..f5c1fb24 --- /dev/null +++ b/Easy/Goal Parser Interpretation.java @@ -0,0 +1,23 @@ +class Solution { + public String interpret(String command) { + StringBuilder sb = new StringBuilder(); + int idx = 0; + while (idx < command.length()) { + if (command.charAt(idx) == '(') { + if (command.charAt(idx + 1) == ')') { + sb.append('o'); + idx++; + } else { + idx++; + while (command.charAt(idx) != ')') { + sb.append(command.charAt(idx++)); + } + } + idx++; + } else { + sb.append(command.charAt(idx++)); + } + } + return sb.toString(); + } +} diff --git a/Easy/Goat Latin.java b/Easy/Goat Latin.java index 56c98048..83417b2f 100644 --- a/Easy/Goat Latin.java +++ b/Easy/Goat Latin.java @@ -1,29 +1,19 @@ class Solution { - public String toGoatLatin(String S) { - StringBuilder sb = new StringBuilder(); - StringBuilder endAppend = new StringBuilder("a"); - final String CONSTANT_APPEND = "ma"; - int start = 0; - int end = 0; - int n = S.length(); - while (end < n) { - while (end < n && S.charAt(end) != ' ') { - end++; - } - char c = Character.toLowerCase(S.charAt(start)); - if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') { - sb.append(S.substring(start, end)).append(CONSTANT_APPEND).append(endAppend.toString()); - } - else { - sb.append(S.substring(start + 1, end)).append(S.charAt(start)).append(CONSTANT_APPEND).append(endAppend.toString()); - } - endAppend.append('a'); - end++; - start = end; - if (end < n) { - sb.append(' '); + public String toGoatLatin(String sentence) { + String[] words = sentence.split("\\s+"); + StringBuilder result = new StringBuilder(); + StringBuilder aWord = new StringBuilder(); + Set vowels = Set.of('a', 'e', 'i', 'o', 'u'); + for (String word : words) { + aWord.append('a'); + char firstChar = word.charAt(0); + if (vowels.contains(Character.toLowerCase(firstChar))) { + result.append(word).append("ma"); + } else { + result.append(word.substring(1)).append(firstChar).append("ma"); } + result.append(aWord.toString()).append(" "); } - return sb.toString(); + return result.toString().trim(); } } diff --git a/Easy/Greatest Common Divisor of Strings.java b/Easy/Greatest Common Divisor of Strings.java index 3a08a29f..f817725a 100644 --- a/Easy/Greatest Common Divisor of Strings.java +++ b/Easy/Greatest Common Divisor of Strings.java @@ -1,36 +1,13 @@ class Solution { public String gcdOfStrings(String str1, String str2) { - return stringGcd(str1, str2); + if (!(str1 + str2).equals(str2 + str1)) { + return ""; + } + int gcdLength = gcd(str1.length(), str2.length()); + return str1.substring(0, gcdLength); } - private String stringGcd(String s1, String s2) { - if (s1.length() == 0) { - return s2; - } - - if (s2.length() == 0) { - return s1; - } - - if (s1.equals(s2)) { - return s1; - } - - if (s1.length() > s2.length()) { - for (int i = 0; i < s2.length(); i++) { - if (s1.charAt(i) != s2.charAt(i)) { - return ""; - } - } - - String temp = s1.substring(s2.length()); - return stringGcd(temp, s2); - } - - if (s2.length() > s1.length()) { - return stringGcd(s2, s1); - } - - return ""; + private int gcd(int x, int y) { + return y == 0 ? x : gcd(y, x % y); } } diff --git a/Easy/Greatest English Letter in Upper and Lower Case.java b/Easy/Greatest English Letter in Upper and Lower Case.java new file mode 100644 index 00000000..2b7028ad --- /dev/null +++ b/Easy/Greatest English Letter in Upper and Lower Case.java @@ -0,0 +1,19 @@ +class Solution { + public String greatestLetter(String s) { + boolean[] upperCasePresent = new boolean[26]; + boolean[] lowerCasePresent = new boolean[26]; + for (char c : s.toCharArray()) { + if (Character.isUpperCase(c)) { + upperCasePresent[c - 'A'] = true; + } else { + lowerCasePresent[c - 'a'] = true; + } + } + for (int i = 25; i >= 0; i--) { + if (upperCasePresent[i] && lowerCasePresent[i]) { + return String.valueOf((char) ('A' + i)); + } + } + return ""; + } +} diff --git a/Easy/Guess Number Higher or Lower.java b/Easy/Guess Number Higher or Lower.java index e10f90ab..91b9aeb0 100644 --- a/Easy/Guess Number Higher or Lower.java +++ b/Easy/Guess Number Higher or Lower.java @@ -13,15 +13,13 @@ public int guessNumber(int n) { int end = n; while (start <= end) { int mid = start + (end - start) / 2; - int res = guess(mid); - if (res == 0) { - return mid; - } - else if (res == -1) { + int result = guess(mid); + if (result == -1) { end = mid - 1; - } - else { + } else if (result == 1) { start = mid + 1; + } else { + return mid; } } return -1; diff --git a/Easy/Happy Number.java b/Easy/Happy Number.java index 13adce96..0884e3a1 100644 --- a/Easy/Happy Number.java +++ b/Easy/Happy Number.java @@ -1,27 +1,21 @@ class Solution { public boolean isHappy(int n) { - Set set = new HashSet<>(); - set.add(n); - while (true) { - int sumOfDigitSquare = getSumOfDigitSquare(n); - if (sumOfDigitSquare == 1) { - return true; - } - if (set.contains(sumOfDigitSquare)) { - break; - } - set.add(sumOfDigitSquare); - n = sumOfDigitSquare; + int slow = n; + int fast = getSquareDigitSum(n); + while (fast != 1 && slow != fast) { + slow = getSquareDigitSum(slow); + fast = getSquareDigitSum(getSquareDigitSum(fast)); } - return false; + return fast == 1; } - private int getSumOfDigitSquare(int n) { - int sum = 0; + private int getSquareDigitSum(int n) { + int squareDigitSum = 0; while (n > 0) { - sum += (int) Math.pow(n % 10, 2); + int digit = n % 10; + squareDigitSum += digit * digit; n /= 10; } - return sum; + return squareDigitSum; } } diff --git a/Easy/Harshad Number.java b/Easy/Harshad Number.java new file mode 100644 index 00000000..c02c40bf --- /dev/null +++ b/Easy/Harshad Number.java @@ -0,0 +1,15 @@ +class Solution { + public int sumOfTheDigitsOfHarshadNumber(int x) { + int digitSum = getDigitSum(x); + return x % digitSum == 0 ? digitSum : -1; + } + + private static int getDigitSum(int num) { + int sum = 0; + while (num > 0) { + sum += num % 10; + num /= 10; + } + return sum; + } +} diff --git a/Easy/Height Checker.java b/Easy/Height Checker.java index 56949329..97bc01d0 100644 --- a/Easy/Height Checker.java +++ b/Easy/Height Checker.java @@ -1,13 +1,20 @@ class Solution { public int heightChecker(int[] heights) { - int[] copy = Arrays.copyOf(heights, heights.length); - Arrays.sort(copy); - int count = 0; - for (int i = 0; i < heights.length; i++) { - if (heights[i] != copy[i]) { - count++; + int[] frequencies = new int[101]; + for (int height : heights) { + frequencies[height]++; + } + int currHeight = 1; + int mismatchCount = 0; + for (int height : heights) { + while (frequencies[currHeight] == 0) { + currHeight++; + } + if (currHeight != height) { + mismatchCount++; } + frequencies[currHeight]--; } - return count; + return mismatchCount; } } diff --git a/Easy/High Five.java b/Easy/High Five.java index 31eb4999..86635d5a 100644 --- a/Easy/High Five.java +++ b/Easy/High Five.java @@ -1,37 +1,23 @@ class Solution { - public int[][] highFive(int[][] items) { - final int COUNT = 5; - Map> map = new HashMap<>(); - Set set = new TreeSet<>(); - - for (int[] item : items) { - int id = item[0]; - int score = item[1]; - - map.computeIfAbsent(id, k -> new PriorityQueue<>(COUNT, Comparator.naturalOrder())).add(score); - - if (map.get(id).size() > COUNT) { - map.get(id).poll(); - } - - set.add(id); - } - - int[][] ans = new int[map.size()][2]; - int idx = 0; - Iterator iterator = set.iterator(); - while (iterator.hasNext()) { - int id = iterator.next(); - PriorityQueue scores = map.get(id); - int sum = 0; - - while (!scores.isEmpty()) { - sum += scores.poll(); - } - - ans[idx++] = new int[]{id, sum / COUNT}; - } - - return ans; + public int[][] highFive(int[][] items) { + Map> map = new HashMap<>(); + for (int[] item : items) { + int id = item[0]; + int score = item[1]; + map.computeIfAbsent(id, k -> new PriorityQueue<>((a, b) -> b - a)).add(score); } + int[][] result = new int[map.size()][2]; + int idx = 0; + for (Integer id : map.keySet()) { + PriorityQueue scoresInOrder = map.get(id); + int totalScore = 0; + int count = Math.min(5, scoresInOrder.size()); + for (int i = 0; i < 5 && !scoresInOrder.isEmpty(); i++) { + totalScore += scoresInOrder.poll(); + } + result[idx++] = new int[]{id, totalScore / count}; + } + Arrays.sort(result, (a, b) -> a[0] - b[0]); + return result; + } } diff --git a/Easy/House Robber.java b/Easy/House Robber.java deleted file mode 100644 index 6ec92f46..00000000 --- a/Easy/House Robber.java +++ /dev/null @@ -1,14 +0,0 @@ -class Solution { - public int rob(int[] nums) { - if (nums.length == 0) { - return 0; - } - int[] dp = new int[nums.length + 1]; - dp[0] = 0; - dp[1] = nums[0]; - for (int i = 1; i < nums.length; i++) { - dp[i + 1] = Math.max(dp[i], dp[i - 1] + nums[i]); - } - return dp[nums.length]; - } -} diff --git a/Easy/How Many Apples Can You Put into the Basket.java b/Easy/How Many Apples Can You Put into the Basket.java index 4626ce53..5e6b8543 100644 --- a/Easy/How Many Apples Can You Put into the Basket.java +++ b/Easy/How Many Apples Can You Put into the Basket.java @@ -1,12 +1,18 @@ class Solution { - public int maxNumberOfApples(int[] arr) { - int weight = 0; - int currCount = 0; - Arrays.sort(arr); - for (int i = 0; i < arr.length && weight + arr[i] <= 5000; i++) { - weight += arr[i]; - currCount++; + public int maxNumberOfApples(int[] weight) { + int[] counter = new int[1001]; + for (int w : weight) { + counter[w]++; } - return currCount; + int numberOfApples = 0; + int totalWeight = 0; + for (int i = 1; i < counter.length && totalWeight <= 5000; i++) { + int count = counter[i]; + while (count-- > 0 && totalWeight + i <= 5000) { + numberOfApples++; + totalWeight += i; + } + } + return numberOfApples; } } diff --git a/Easy/Image Smoother.java b/Easy/Image Smoother.java index 9f0d68f0..ede06daf 100644 --- a/Easy/Image Smoother.java +++ b/Easy/Image Smoother.java @@ -1,49 +1,27 @@ class Solution { - public int[][] imageSmoother(int[][] M) { - - int[][] res = new int[M.length][M[0].length]; - for (int i=0;i= 0) { - count++; - sum += M[i][j-1]; - } - if(j+1 < M[0].length) { - count++; - sum += M[i][j+1]; - } - if(i-1 >= 0) { - count++; - sum += M[i-1][j]; - } - if(i+1 < M.length) { - count++; - sum += M[i+1][j]; - } - if(i+1 < M.length && j+1 < M[0].length) { - count++; - sum += M[i+1][j+1]; - } - if(i+1 < M.length && j-1 >= 0) { - count++; - sum += M[i+1][j-1]; - } - if(i-1 >= 0 && j-1 >= 0) { - count++; - sum += M[i-1][j-1]; - } - if(i-1 >= 0 && j+1 < M[0].length) { - count++; - sum += M[i-1][j+1]; - } - - res[i][j] = (int)Math.floor(sum/count); + for (int[] dir : DIRS) { + int row = i + dir[0]; + int col = j + dir[1]; + if (row >= 0 && row < rows && col >= 0 && col < cols) { + sum += img[row][col]; + count++; + } + } + double smoothImage = sum / count; + result[i][j] = (int) smoothImage; } } - - return res; + return result; } } diff --git a/Easy/Implement Queue using Stacks.java b/Easy/Implement Queue using Stacks.java index c2a5254d..a84da8b6 100644 --- a/Easy/Implement Queue using Stacks.java +++ b/Easy/Implement Queue using Stacks.java @@ -1,46 +1,40 @@ class MyQueue { - /** Initialize your data structure here. */ - Stack stack; - Stack revStack; - public MyQueue() { - stack = new Stack<>(); - revStack = new Stack<>(); - } + private final Stack first; + private final Stack second; - /** Push element x to the back of queue. */ - public void push(int x) { - stack.push(x); - } - - /** Removes the element from in front of queue and returns that element. */ - public int pop() { - while (!stack.isEmpty()) { - revStack.push(stack.pop()); + public MyQueue() { + this.first = new Stack<>(); + this.second = new Stack<>(); } - int num = revStack.pop(); - while (!revStack.isEmpty()) { - stack.push(revStack.pop()); + + public void push(int x) { + first.push(x); } - return num; - } - - /** Get the front element. */ - public int peek() { - while (!stack.isEmpty()) { - revStack.push(stack.pop()); + + public int pop() { + move(first, second); + int result = second.pop(); + move(second, first); + return result; } - int num = revStack.peek(); - while (!revStack.isEmpty()) { - stack.push(revStack.pop()); + + public int peek() { + move(first, second); + int result = second.peek(); + move(second, first); + return result; + } + + public boolean empty() { + return first.isEmpty(); } - return num; - } - /** Returns whether the queue is empty. */ - public boolean empty() { - return stack.isEmpty(); - } + private void move(Stack from, Stack to) { + while (!from.isEmpty()) { + to.push(from.pop()); + } + } } /** diff --git a/Easy/Implement Stack using Queues.java b/Easy/Implement Stack using Queues.java index 08df7392..d93ce3ae 100644 --- a/Easy/Implement Stack using Queues.java +++ b/Easy/Implement Stack using Queues.java @@ -1,43 +1,50 @@ -import java.util.ArrayList; - class MyStack { + + private final Queue mainQueue; + private final Queue backupQueue; - /** Initialize your data structure here. */ - ArrayList arrNew = new ArrayList<>(); - ArrayList arrOld = new ArrayList<>(); - - - /** Push element x onto stack. */ + public MyStack() { + this.mainQueue = new LinkedList<>(); + this.backupQueue = new LinkedList<>(); + } + public void push(int x) { - arrOld.add(x); + this.mainQueue.add(x); } - - /** Removes the element on top of the stack and returns that element. */ + public int pop() { - for (int i=0;i<=arrOld.size()-1;i++) { - arrNew.add(arrOld.get(i)); - } - int k = arrNew.get(arrNew.size()-1); - arrNew.remove(arrNew.indexOf(k)); - - arrOld.clear(); - return k; + int lastElement = moveToBackupQueue(); + moveToMainQueue(true); + return lastElement; } - - /** Get the top element. */ + public int top() { - for (int i=0;i<=arrOld.size()-1;i++) { - arrNew.add(arrOld.get(i)); - } - int k = arrNew.get(arrNew.size()-1); - - arrOld.clear(); - return k; + int lastElement = moveToBackupQueue(); + moveToMainQueue(false); + return lastElement; } - - /** Returns whether the stack is empty. */ + public boolean empty() { - return arrNew.size() == 0 && arrOld.size() == 0; + return this.mainQueue.isEmpty(); + } + + private int moveToBackupQueue() { + int lastElement = this.mainQueue.peek(); + while (!this.mainQueue.isEmpty()) { + lastElement = this.mainQueue.peek(); + this.backupQueue.add(this.mainQueue.poll()); + } + return lastElement; + } + + private void moveToMainQueue(boolean removeLast) { + int sizeLimit = removeLast ? 1 : 0; + while (this.backupQueue.size() > sizeLimit) { + this.mainQueue.add(this.backupQueue.poll()); + } + if (removeLast) { + this.backupQueue.remove(); + } } } diff --git a/Easy/Implement strStr.java b/Easy/Implement strStr.java index bf12a2ed..ea05ba6f 100644 --- a/Easy/Implement strStr.java +++ b/Easy/Implement strStr.java @@ -1,14 +1,10 @@ class Solution { public int strStr(String haystack, String needle) { - int hayLength = haystack.length(); - int needleLength = needle.length(); - int idx = 0; - while (idx + needleLength <= hayLength) { - if (haystack.substring(idx, idx + needleLength).equals(needle)) { - return idx; + for (int i = 0; i < haystack.length() - needle.length() + 1; i++) { + if (haystack.substring(i, i + needle.length()).equals(needle)) { + return i; } - idx++; } return -1; - } + } } diff --git a/Easy/Increasing Order Search Tree.java b/Easy/Increasing Order Search Tree.java index 4039276d..1ca57c9b 100644 --- a/Easy/Increasing Order Search Tree.java +++ b/Easy/Increasing Order Search Tree.java @@ -4,26 +4,36 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - TreeNode curr; public TreeNode increasingBST(TreeNode root) { - TreeNode ans = new TreeNode(-1); - curr = ans; - inorder(root); - return ans.right; - } - - private void inorder(TreeNode node) { - if (node == null) { - return; + Stack stack = new Stack<>(); + while (root != null) { + stack.push(root); + root = root.left; + } + TreeNode newHead = null; + while (!stack.isEmpty()) { + TreeNode removed = stack.pop(); + if (newHead == null) { + newHead = removed; + } + TreeNode rightNode = removed.right; + while (rightNode != null) { + stack.push(rightNode); + rightNode = rightNode.left; + } + removed.right = stack.isEmpty() ? null : stack.peek(); + removed.left = null; } - inorder(node.left); - node.left = null; - curr.right = node; - curr = node; - inorder(node.right); + return newHead; } } diff --git a/Easy/Index Pairs of a String.java b/Easy/Index Pairs of a String.java index 97d590ce..5fd32b1e 100644 --- a/Easy/Index Pairs of a String.java +++ b/Easy/Index Pairs of a String.java @@ -1,50 +1,14 @@ class Solution { - public int[][] indexPairs(String text, String[] words) { - TrieNode root = new TrieNode('-'); - for (String word : words) { - addWord(word, root); - } - List list = new ArrayList<>(); - for (int i = 0; i < text.length(); i++) { - int j = i; - TrieNode curr = root; - while (j < text.length() && curr.childrens.containsKey(text.charAt(j))) { - curr = curr.childrens.get(text.charAt(j)); - if (curr.isWord) { - list.add(new int[]{i, j}); + public int[][] indexPairs(String text, String[] words) { + List pairs = new ArrayList<>(); + for (String word : words) { + for (int i = 0; i < text.length() - word.length() + 1; i++) { + if (text.startsWith(word, i)) { + pairs.add(new int[]{i, i + word.length() - 1}); + } + } } - j++; - } - } - int[][] ans = new int[list.size()][2]; - for (int i = 0; i < list.size(); i++) { - ans[i] = list.get(i); + pairs.sort(Comparator.comparingInt((int[] o) -> o[0]).thenComparingInt(o -> o[1])); + return pairs.toArray(new int[0][]); } - return ans; - } - - private void addWord(String s, TrieNode root) { - for (int i = 0; i < s.length(); i++) { - if (!root.childrens.containsKey(s.charAt(i))) { - root.childrens.put(s.charAt(i), new TrieNode(s.charAt(i))); - } - root = root.childrens.get(s.charAt(i)); - if (i == s.length() - 1) { - root.isWord = true; - } - } - } -} - - -class TrieNode { - char c; - Map childrens; - boolean isWord; - - public TrieNode(char c) { - this.c = c; - childrens = new HashMap<>(); - isWord = false; - } } diff --git a/Easy/Intersection of Multiple Arrays.java b/Easy/Intersection of Multiple Arrays.java new file mode 100644 index 00000000..f06c30b8 --- /dev/null +++ b/Easy/Intersection of Multiple Arrays.java @@ -0,0 +1,19 @@ +import java.util.Map.Entry; + + +class Solution { + public List intersection(int[][] nums) { + Map counter = new HashMap<>(); + for (int[] num : nums) { + for (int element : num) { + counter.put(element, counter.getOrDefault(element, 0) + 1); + } + } + return counter.entrySet() + .stream() + .filter(entry -> entry.getValue() == nums.length) + .map(Entry::getKey) + .sorted() + .collect(Collectors.toList()); + } +} diff --git a/Easy/Intersection of Three Sorted Arrays.java b/Easy/Intersection of Three Sorted Arrays.java index 71e66b1c..d7dc12e5 100644 --- a/Easy/Intersection of Three Sorted Arrays.java +++ b/Easy/Intersection of Three Sorted Arrays.java @@ -1,21 +1,28 @@ class Solution { public List arraysIntersection(int[] arr1, int[] arr2, int[] arr3) { - int[] counter = new int[2001]; - updateCounter(counter, arr1); - updateCounter(counter, arr2); - updateCounter(counter, arr3); - List ans = new ArrayList<>(); - for (int i = 0; i < 2001; i++) { - if (counter[i] == 3) { - ans.add(i); + int idxOne = 0; + int idxTwo = 0; + int idxThree = 0; + List result = new ArrayList<>(); + while (idxOne < arr1.length && idxTwo < arr2.length && idxThree < arr3.length) { + if (arr1[idxOne] == arr2[idxTwo] && arr2[idxTwo] == arr3[idxThree]) { + result.add(arr1[idxOne]); + idxOne++; + idxTwo++; + idxThree++; + } else { + int max = Math.max(arr1[idxOne], Math.max(arr2[idxTwo], arr3[idxThree])); + if (arr1[idxOne] < max) { + idxOne++; + } + if (arr2[idxTwo] < max) { + idxTwo++; + } + if (arr3[idxThree] < max) { + idxThree++; + } } } - return ans; - } - - private void updateCounter(int[] counter, int[] arr) { - for (int num : arr) { - counter[num]++; - } + return result; } } diff --git a/Easy/Intersection of Two Arrays II.java b/Easy/Intersection of Two Arrays II.java new file mode 100644 index 00000000..6a6b143d --- /dev/null +++ b/Easy/Intersection of Two Arrays II.java @@ -0,0 +1,14 @@ +class Solution { + public int[] intersect(int[] nums1, int[] nums2) { + Map map = Arrays.stream(nums1).boxed() + .collect(Collectors.groupingBy(Function.identity(), HashMap::new, Collectors.counting())); + List result = new ArrayList<>(); + for (int num : nums2) { + if (map.getOrDefault(num, 0L) > 0) { + result.add(num); + map.put(num, map.get(num) - 1); + } + } + return result.stream().mapToInt(Integer::valueOf).toArray(); + } +} diff --git a/Easy/Intersection of Two Arrays.java b/Easy/Intersection of Two Arrays.java index b17c8dea..24a47d60 100644 --- a/Easy/Intersection of Two Arrays.java +++ b/Easy/Intersection of Two Arrays.java @@ -1,20 +1,8 @@ class Solution { - public int[] intersection(int[] nums1, int[] nums2) { - Set set = new HashSet<>(); - for (int num : nums1) { - set.add(num); + public int[] intersection(int[] nums1, int[] nums2) { + Set set1 = Arrays.stream(nums1).boxed().collect(Collectors.toSet()); + Set set2 = Arrays.stream(nums2).boxed().collect(Collectors.toSet()); + set1.retainAll(set2); + return set1.stream().mapToInt(Integer::intValue).toArray(); } - Set match = new HashSet<>(); - for (int num : nums2) { - if (set.contains(num)) { - match.add(num); - } - } - int[] ans = new int[match.size()]; - Iterator iter = match.iterator(); - for (int i = 0; i < ans.length; i++) { - ans[i] = iter.next(); - } - return ans; - } } diff --git a/Easy/Intersection of two Linked Lists.java b/Easy/Intersection of two Linked Lists.java index f515b847..2da135fb 100644 --- a/Easy/Intersection of two Linked Lists.java +++ b/Easy/Intersection of two Linked Lists.java @@ -11,38 +11,12 @@ */ public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { - int lenA = getLength(headA); - int lenB = getLength(headB); - ListNode currA = headA; - ListNode currB = headB; - if (lenA > lenB) { - int diff = lenA - lenB; - while (diff-- > 0) { - currA = currA.next; - } + ListNode copyA = headA; + ListNode copyB = headB; + while (copyA != copyB) { + copyA = copyA == null ? headB : copyA.next; + copyB = copyB == null ? headA : copyB.next; } - if (lenB > lenA) { - int diff = lenB - lenA; - while (diff-- > 0) { - currB = currB.next; - } - } - while (currA != null && currB != null) { - if (currA == currB) { - return currA; - } - currA = currA.next; - currB = currB.next; - } - return null; - } - - private int getLength(ListNode node) { - int len = 0; - while (node != null) { - node = node.next; - len++; - } - return len; + return copyA; } } diff --git a/Easy/Intersection of two arrays II.java b/Easy/Intersection of two arrays II.java deleted file mode 100644 index 69407386..00000000 --- a/Easy/Intersection of two arrays II.java +++ /dev/null @@ -1,20 +0,0 @@ -class Solution { - public int[] intersect(int[] nums1, int[] nums2) { - Map map = new HashMap<>(); - for (int num : nums1) { - map.put(num, map.getOrDefault(num, 0) + 1); - } - List list = new ArrayList<>(); - for (int num : nums2) { - if (map.getOrDefault(num, 0) > 0) { - list.add(num); - map.put(num, map.get(num) - 1); - } - } - int[] ans = new int[list.size()]; - for (int i = 0; i < list.size(); i++) { - ans[i] = list.get(i); - } - return ans; - } -} diff --git a/Easy/Invert Binary Tree.java b/Easy/Invert Binary Tree.java index f02950d0..d2c3c6ab 100644 --- a/Easy/Invert Binary Tree.java +++ b/Easy/Invert Binary Tree.java @@ -14,15 +14,13 @@ * } */ class Solution { - public TreeNode invertTree(TreeNode root) { - if (root == null) { - return root; + public TreeNode invertTree(TreeNode root) { + if (root == null) { + return null; + } + TreeNode leftNode = root.left; + root.left = invertTree(root.right); + root.right = invertTree(leftNode); + return root; } - TreeNode right = root.right; - root.right = root.left; - root.left = right; - invertTree(root.left); - invertTree(root.right); - return root; - } } diff --git a/Easy/Is Subsequence.java b/Easy/Is Subsequence.java index fc28d621..2d67a698 100644 --- a/Easy/Is Subsequence.java +++ b/Easy/Is Subsequence.java @@ -1,15 +1,13 @@ class Solution { - public boolean isSubsequence(String s, String t) { - int idxS = 0; - int idxT = 0; - int lenS = s.length(); - int lenT = t.length(); - while (idxS < lenS && idxT < lenT) { - if (s.charAt(idxS) == t.charAt(idxT)) { - idxS++; - } - idxT++; + public boolean isSubsequence(String s, String t) { + int sIdx = 0; + int tIdx = 0; + while (sIdx < s.length() && tIdx < t.length()) { + if (s.charAt(sIdx) == t.charAt(tIdx)) { + sIdx++; + } + tIdx++; + } + return sIdx == s.length(); } - return idxS == lenS; - } } diff --git a/Easy/Isomorphic Strings.java b/Easy/Isomorphic Strings.java index 365f4ce6..b9813b64 100644 --- a/Easy/Isomorphic Strings.java +++ b/Easy/Isomorphic Strings.java @@ -1,10 +1,18 @@ class Solution { - public boolean isIsomorphic(String s1, String s2) { - int[] m = new int[512]; - for (int i = 0; i < s1.length(); i++) { - if (m[s1.charAt(i)] != m[s2.charAt(i)+256]) return false; - m[s1.charAt(i)] = m[s2.charAt(i)+256] = i+1; + public boolean isIsomorphic(String s, String t) { + return mapString(s).equals(mapString(t)); + } + + private static String mapString(String s) { + Map map = new HashMap<>(); + int count = 0; + StringBuilder sb = new StringBuilder(); + for (char c : s.toCharArray()) { + if (!map.containsKey(c)) { + map.put(c, count++); + } + sb.append(map.get(c)).append("|"); } - return true; + return sb.toString(); } } diff --git a/Easy/K Closest Points to Origin.java b/Easy/K Closest Points to Origin.java deleted file mode 100644 index 950e2783..00000000 --- a/Easy/K Closest Points to Origin.java +++ /dev/null @@ -1,36 +0,0 @@ -class Solution { - public int[][] kClosest(int[][] points, int K) { - int[][] ans = new int[K][2]; - PriorityQueue pq = new PriorityQueue<>(new Comparator() { - @Override - public int compare(int[] o1, int[] o2) { - double dist1 = getDistance(o1); - double dist2 = getDistance(o2); - - if (dist1 > dist2) { - return 1; - } - else if (dist1 < dist2) { - return -1; - } - else { - return 0; - } - } - }); - - for (int[] point : points) { - pq.add(point); - } - - for (int i=0; i map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } int count = 0; - while (left < nums.length && right < nums.length) { - if (left == right || nums[right] - nums[left] < k) { - right++; - } - else if (nums[right] - nums[left] > k) { - left++; - } - else { - left++; - count++; - while (left < nums.length && nums[left] == nums[left - 1]) { - left++; + for (Map.Entry entry : map.entrySet()) { + if (k == 0) { + if (entry.getValue() >= 2) { + count++; + } + } else { + if (map.containsKey(entry.getKey() + k)) { + count++; } } } diff --git a/Easy/Keep Multiplying Found Values by Two.java b/Easy/Keep Multiplying Found Values by Two.java new file mode 100644 index 00000000..165e4b74 --- /dev/null +++ b/Easy/Keep Multiplying Found Values by Two.java @@ -0,0 +1,12 @@ +class Solution { + public int findFinalValue(int[] nums, int original) { + Set set = new HashSet<>(); + for (int num : nums) { + set.add(num); + } + while (set.contains(original)) { + original *= 2; + } + return original; + } +} diff --git a/Easy/Kids With the Greatest Number of Candies.java b/Easy/Kids With the Greatest Number of Candies.java index 69e60fb2..67e2441d 100644 --- a/Easy/Kids With the Greatest Number of Candies.java +++ b/Easy/Kids With the Greatest Number of Candies.java @@ -1,13 +1,10 @@ class Solution { - public List kidsWithCandies(int[] candies, int extraCandies) { - int max = Integer.MIN_VALUE; - for (int candy : candies) { - max = Math.max(max, candy); + public List kidsWithCandies(int[] candies, int extraCandies) { + final int maxCandy = Arrays.stream(candies) + .max() + .orElse(0); + return Arrays.stream(candies) + .mapToObj(candy -> candy + extraCandies >= maxCandy) + .collect(Collectors.toList()); } - List ans = new ArrayList<>(); - for (int i = 0; i < candies.length; i++) { - ans.add((candies[i] + extraCandies) >= max); - } - return ans; - } } diff --git a/Easy/Kth Distinct String in an Array.java b/Easy/Kth Distinct String in an Array.java new file mode 100644 index 00000000..31a474f7 --- /dev/null +++ b/Easy/Kth Distinct String in an Array.java @@ -0,0 +1,11 @@ +import java.util.Map.Entry; + +class Solution { + public String kthDistinct(String[] arr, int k) { + return Arrays.stream(arr).collect( + Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting())) + .entrySet().stream().filter(entry -> entry.getValue().equals(1L)).map(Entry::getKey) + .skip(k - 1) + .findFirst().orElse(""); + } +} diff --git a/Easy/Kth Largest Element in a Stream.java b/Easy/Kth Largest Element in a Stream.java index e3ab89a0..4b1868f3 100644 --- a/Easy/Kth Largest Element in a Stream.java +++ b/Easy/Kth Largest Element in a Stream.java @@ -1,24 +1,28 @@ class KthLargest { - PriorityQueue pq; - int k; - public KthLargest(int k, int[] nums) { - pq = new PriorityQueue<>(); - this.k = k; - for (int num : nums) { - add(num); - } - } + + private final PriorityQueue pq; + private final int k; - public int add(int num) { - if (pq.size() < k) { - pq.add(num); + public KthLargest(int k, int[] nums) { + this.k = k; + this.pq = new PriorityQueue<>((a, b) -> a - b); + for (int num : nums) { + pq.add(num); + checkLength(); + } + } + + public int add(int val) { + pq.add(val); + checkLength(); + return pq.peek(); } - else if (pq.peek() < num) { - pq.poll(); - pq.add(num); + + private void checkLength() { + if (pq.size() > k) { + pq.poll(); + } } - return pq.peek(); - } } /** diff --git a/Easy/Kth Missing Positive Integer.java b/Easy/Kth Missing Positive Integer.java deleted file mode 100644 index 9721a3c4..00000000 --- a/Easy/Kth Missing Positive Integer.java +++ /dev/null @@ -1,22 +0,0 @@ -class Solution { - public int findKthPositive(int[] arr, int k) { - int missCount = 0; - for (int i = 0; i < arr.length; i++) { - int curr = arr[i]; - int prev = i == 0 ? 0 : arr[i - 1]; - while (prev < (curr - 1)) { - missCount++; - prev++; - if (missCount == k) { - return prev; - } - } - } - int curr = arr[arr.length - 1]; - while (missCount < k) { - curr++; - missCount++; - } - return curr; - } -} diff --git a/Easy/Kth Missing Positive Number.java b/Easy/Kth Missing Positive Number.java new file mode 100644 index 00000000..6f662c97 --- /dev/null +++ b/Easy/Kth Missing Positive Number.java @@ -0,0 +1,15 @@ +class Solution { + public int findKthPositive(int[] arr, int k) { + int left = 0; + int right = arr.length - 1; + while (left <= right) { + int mid = left + (right - left) / 2; + if (arr[mid] - mid - 1 < k) { + left = mid + 1; + } else { + right = mid - 1; + } + } + return left + k; + } +} diff --git a/Easy/Largest 3-Same-Digit Number in String.java b/Easy/Largest 3-Same-Digit Number in String.java new file mode 100644 index 00000000..6d0b2680 --- /dev/null +++ b/Easy/Largest 3-Same-Digit Number in String.java @@ -0,0 +1,13 @@ +class Solution { + public String largestGoodInteger(String num) { + int largestIdx = -1; + for (int i = 0; i < num.length() - 2; i++) { + if (num.charAt(i) == num.charAt(i + 1) && num.charAt(i + 1) == num.charAt(i + 2)) { + if (largestIdx == -1 || num.substring(largestIdx, largestIdx + 3).compareTo(num.substring(i, i + 3)) < 0) { + largestIdx = i; + } + } + } + return largestIdx == -1 ? "" : num.substring(largestIdx, largestIdx + 3); + } +} diff --git a/Easy/Largest Local Values in a Matrix.java b/Easy/Largest Local Values in a Matrix.java new file mode 100644 index 00000000..570443a9 --- /dev/null +++ b/Easy/Largest Local Values in a Matrix.java @@ -0,0 +1,17 @@ +class Solution { + public int[][] largestLocal(int[][] grid) { + int rows = grid.length; + int cols = grid[0].length; + int[][] result = new int[rows - 2][cols - 2]; + for (int i = 0; i < rows - 2; i++) { + for (int j = 0; j < cols - 2; j++) { + for (int k = i; k < i + 3; k++) { + for (int l = j; l < j + 3; l++) { + result[i][j] = Math.max(result[i][j], grid[k][l]); + } + } + } + } + return result; + } +} diff --git a/Easy/Largest Number After Digit Swaps by Parity.java b/Easy/Largest Number After Digit Swaps by Parity.java new file mode 100644 index 00000000..1959ca40 --- /dev/null +++ b/Easy/Largest Number After Digit Swaps by Parity.java @@ -0,0 +1,28 @@ +class Solution { + public int largestInteger(int num) { + char[] digits = String.valueOf(num).toCharArray(); + int[] frequency = new int[10]; + for (int i = 0; i < digits.length; i++) { + frequency[digits[i] - '0']++; + } + int largestNumber = 0; + int evenIdx = 8; + int oddIdx = 9; + for (int i = 0; i < digits.length; i++) { + if (digits[i] % 2 == 0) { + while (frequency[evenIdx] == 0) { + evenIdx -= 2; + } + frequency[evenIdx]--; + largestNumber = largestNumber * 10 + evenIdx; + } else { + while (frequency[oddIdx] == 0) { + oddIdx -= 2; + } + frequency[oddIdx]--; + largestNumber = largestNumber * 10 + oddIdx; + } + } + return largestNumber; + } +} diff --git a/Easy/Largest Odd Number in String.java b/Easy/Largest Odd Number in String.java new file mode 100644 index 00000000..b43d4726 --- /dev/null +++ b/Easy/Largest Odd Number in String.java @@ -0,0 +1,10 @@ +class Solution { + public String largestOddNumber(String num) { + for (int i = num.length() - 1; i >= 0; i--) { + if (Character.getNumericValue(num.charAt(i)) % 2 != 0) { + return num.substring(0, i + 1); + } + } + return ""; + } +} diff --git a/Easy/Largest Perimeter Triangle.java b/Easy/Largest Perimeter Triangle.java index bc9803f5..c298121d 100644 --- a/Easy/Largest Perimeter Triangle.java +++ b/Easy/Largest Perimeter Triangle.java @@ -1,14 +1,11 @@ class Solution { - public int largestPerimeter(int[] A) { - Arrays.sort(A); - int n = A.length; - - for (int i=n-1; i>1; i--) { - if (A[i] < A[i - 1] + A[i - 2]) { - return A[i] + A[i - 1] + A[i - 2]; - } - } - - return 0; + public int largestPerimeter(int[] nums) { + Arrays.sort(nums); + for (int i = nums.length - 3; i >= 0; i--) { + if (nums[i] + nums[i + 1] > nums[i + 2]) { + return nums[i] + nums[i + 1] + nums[i + 2]; + } } + return 0; + } } diff --git a/Easy/Largest Positive Integer That Exists With Its Negative.java b/Easy/Largest Positive Integer That Exists With Its Negative.java new file mode 100644 index 00000000..b6789be7 --- /dev/null +++ b/Easy/Largest Positive Integer That Exists With Its Negative.java @@ -0,0 +1,13 @@ +class Solution { + public int findMaxK(int[] nums) { + int largestNumber = -1; + Set set = new HashSet<>(); + for (int num : nums) { + if (set.contains(-1 * num)) { + largestNumber = Math.max(Math.abs(num), largestNumber); + } + set.add(num); + } + return largestNumber; + } +} diff --git a/Easy/Largest Substring Between Two Equal Characters.java b/Easy/Largest Substring Between Two Equal Characters.java new file mode 100644 index 00000000..24371003 --- /dev/null +++ b/Easy/Largest Substring Between Two Equal Characters.java @@ -0,0 +1,11 @@ +class Solution { + public int maxLengthBetweenEqualCharacters(String s) { + Map map = new HashMap<>(); + int maxLength = -1; + for (int i = 0; i < s.length(); i++) { + map.putIfAbsent(s.charAt(i), i); + maxLength = Math.max(maxLength, i - map.get(s.charAt(i)) - 1); + } + return maxLength; + } +} diff --git a/Easy/Largest Time for Given Digits.java b/Easy/Largest Time for Given Digits.java deleted file mode 100644 index 51ab3232..00000000 --- a/Easy/Largest Time for Given Digits.java +++ /dev/null @@ -1,25 +0,0 @@ -class Solution { - public String largestTimeFromDigits(int[] A) { - int ans = -1; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - if (i != j) { - for (int k = 0; k < 4; k++) { - if (i != k && j != k) { - for (int l = 0; l < 4; l++) { - if (l != i && l != j && l != k) { - int hours = 10 * A[i] + A[j]; - int mins = 10 * A[k] + A[l]; - if (hours < 24 && mins < 60) { - ans = Math.max(ans, hours * 60 + mins); - } - } - } - } - } - } - } - } - return ans >= 0 ? String.format("%02d:%02d", ans / 60, ans % 60) : ""; - } -} diff --git a/Easy/Last Stone Weight.java b/Easy/Last Stone Weight.java index abf2a4d9..afb35b41 100644 --- a/Easy/Last Stone Weight.java +++ b/Easy/Last Stone Weight.java @@ -1,16 +1,16 @@ class Solution { - public int lastStoneWeight(int[] stones) { - PriorityQueue pq = new PriorityQueue<>((a, b) -> b - a); - for (int stone : stones) { - pq.add(stone); + public int lastStoneWeight(int[] stones) { + PriorityQueue pq = new PriorityQueue<>((a, b) -> b - a); + for (int stone : stones) { + pq.add(stone); + } + while (pq.size() > 1) { + int stoneOne = pq.poll(); + int stoneTwo = pq.poll(); + if (stoneOne != stoneTwo) { + pq.add(stoneOne - stoneTwo); + } + } + return pq.isEmpty() ? 0 : pq.poll(); } - while (pq.size() > 1) { - int max1 = pq.poll(); - int max2 = pq.poll(); - if (max1 != max2) { - pq.add(max1 - max2); - } - } - return pq.isEmpty() ? 0 : pq.peek(); - } } diff --git a/Easy/Last Visited Integers.java b/Easy/Last Visited Integers.java new file mode 100644 index 00000000..e6a59e34 --- /dev/null +++ b/Easy/Last Visited Integers.java @@ -0,0 +1,17 @@ +class Solution { + public List lastVisitedIntegers(List words) { + List result = new ArrayList<>(); + List numbers = new ArrayList<>(); + int cursor = -1; + for (String word : words) { + if (word.equals("prev")) { + result.add(cursor == -1 ? -1 : numbers.get(cursor)); + cursor = cursor == -1 ? -1 : (cursor - 1); + } else { + numbers.add(Integer.parseInt(word)); + cursor = numbers.size() - 1; + } + } + return result; + } +} diff --git a/Easy/Latest Time by Replacing Hidden Digits.java b/Easy/Latest Time by Replacing Hidden Digits.java new file mode 100644 index 00000000..2bb4a840 --- /dev/null +++ b/Easy/Latest Time by Replacing Hidden Digits.java @@ -0,0 +1,30 @@ +class Solution { + public String maximumTime(String time) { + char[] digits = time.toCharArray(); + if (digits[0] == '?' || digits[1] == '?') { + if (digits[0] == '?') { + if (digits[1] == '?' || Character.getNumericValue(digits[1]) <= 3) { + digits[0] = '2'; + } else { + digits[0] = '1'; + } + } + if (digits[1] == '?') { + if (Character.getNumericValue(digits[0]) <= 1) { + digits[1] = '9'; + } else { + digits[1] = '3'; + } + } + } + if (digits[3] == '?' || digits[4] == '?') { + if (digits[3] == '?') { + digits[3] = '5'; + } + if (digits[4] == '?') { + digits[4] = '9'; + } + } + return String.valueOf(digits); + } +} diff --git a/Easy/Leaf Similar Tree.java b/Easy/Leaf Similar Tree.java deleted file mode 100644 index 5b79aa91..00000000 --- a/Easy/Leaf Similar Tree.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode() {} - * TreeNode(int val) { this.val = val; } - * TreeNode(int val, TreeNode left, TreeNode right) { - * this.val = val; - * this.left = left; - * this.right = right; - * } - * } - */ -class Solution { - public boolean leafSimilar(TreeNode root1, TreeNode root2) { - return getLeafSequence(root1).equals(getLeafSequence(root2)); - } - - private String getLeafSequence(TreeNode root) { - List list = new ArrayList<>(); - helper(root, list); - return list.toString(); - } - - private void helper(TreeNode root, List list) { - if (root == null) { - return; - } - if (root.left == null && root.right == null) { - list.add(root.val); - } - else { - helper(root.left, list); - helper(root.right, list); - } - } -} diff --git a/Easy/Leaf-Similar Trees.java b/Easy/Leaf-Similar Trees.java new file mode 100644 index 00000000..082f6583 --- /dev/null +++ b/Easy/Leaf-Similar Trees.java @@ -0,0 +1,42 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public boolean leafSimilar(TreeNode root1, TreeNode root2) { + return getLeaves(root1).equals(getLeaves(root2)); + } + + private static List getLeaves(TreeNode root) { + if (root == null) { + return new ArrayList<>(); + } + List result = new ArrayList<>(); + Stack stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()) { + TreeNode removed = stack.pop(); + if (removed.left == null && removed.right == null) { + result.add(removed.val); + } + if (removed.right != null) { + stack.push(removed.right); + } + if (removed.left != null) { + stack.push(removed.left); + } + } + return result; + } +} diff --git a/Easy/Left and Right Sum Differences.java b/Easy/Left and Right Sum Differences.java new file mode 100644 index 00000000..99a5338a --- /dev/null +++ b/Easy/Left and Right Sum Differences.java @@ -0,0 +1,17 @@ +class Solution { + public int[] leftRigthDifference(int[] nums) { + int n = nums.length; + int leftToRightSum = 0; + for (int i = 0; i < n; i++) { + leftToRightSum += nums[i]; + } + int[] result = new int[n]; + int rightToLeftSum = 0; + for (int i = n - 1; i >= 0; i--) { + leftToRightSum -= nums[i]; + result[i] = Math.abs(rightToLeftSum - leftToRightSum); + rightToLeftSum += nums[i]; + } + return result; + } +} diff --git a/Easy/Lemonade Change.java b/Easy/Lemonade Change.java new file mode 100644 index 00000000..acddd319 --- /dev/null +++ b/Easy/Lemonade Change.java @@ -0,0 +1,23 @@ +class Solution { + public boolean lemonadeChange(int[] bills) { + int[] billCount = new int[3]; + for (int bill : bills) { + int returnAmount = bill - 5; + for (int i = 2; i >= 0 && returnAmount > 0; i--) { + int amount = i == 2 ? 20 : (i == 1 ? 10 : 5); + if (returnAmount >= amount) { + int billsRequired = returnAmount / amount; + int billsAvailable = billCount[i]; + returnAmount -= Math.min(billsRequired, billsAvailable) * amount; + billCount[i] -= Math.min(billsRequired, billsAvailable); + } + } + if (returnAmount != 0) { + return false; + } + int amountIdx = bill == 20 ? 2 : (bill == 10 ? 1 : 0); + billCount[amountIdx]++; + } + return true; + } +} diff --git a/Easy/Length of last word.java b/Easy/Length of last word.java index 8768e506..a351538e 100644 --- a/Easy/Length of last word.java +++ b/Easy/Length of last word.java @@ -1,14 +1,13 @@ class Solution { public int lengthOfLastWord(String s) { - int count = 0; int idx = s.length() - 1; while (idx >= 0 && s.charAt(idx) == ' ') { idx--; } + int currIdx = idx; while (idx >= 0 && s.charAt(idx) != ' ') { idx--; - count++; } - return count; + return currIdx - idx; } } diff --git a/Easy/Letter Case Permutation.java b/Easy/Letter Case Permutation.java index c451655c..eb1f7d74 100644 --- a/Easy/Letter Case Permutation.java +++ b/Easy/Letter Case Permutation.java @@ -1,29 +1,24 @@ class Solution { public List letterCasePermutation(String S) { - Set set = new HashSet<>(); - helper(S, 0, set, new StringBuilder()); - return new ArrayList<>(set); + List result = new ArrayList<>(); + helper(S, 0, new StringBuilder(), result); + return result; } - private void helper(String s, int idx, Set set, StringBuilder sb) { + private void helper(String s, int idx, StringBuilder sb, List result) { if (idx == s.length()) { - if (sb.length() > 0) { - set.add(new StringBuilder(sb.toString()).toString()); - } - } - else { - char c = s.charAt(idx); - if (Character.isDigit(c)) { - sb.append(c); - helper(s, idx + 1, set, sb); + result.add(new String(sb.toString())); + } else { + if (Character.isDigit(s.charAt(idx))) { + sb.append(s.charAt(idx)); + helper(s, idx + 1, sb, result); sb.deleteCharAt(sb.length() - 1); - } - else { - sb.append(Character.toLowerCase(c)); - helper(s, idx + 1, set, sb); + } else { + sb.append(Character.toLowerCase(s.charAt(idx))); + helper(s, idx + 1, sb, result); sb.deleteCharAt(sb.length() - 1); - sb.append(Character.toUpperCase(c)); - helper(s, idx + 1, set, sb); + sb.append(Character.toUpperCase(s.charAt(idx))); + helper(s, idx + 1, sb, result); sb.deleteCharAt(sb.length() - 1); } } diff --git a/Easy/Logger Rate Limiter.java b/Easy/Logger Rate Limiter.java index 3e637371..6cdc1665 100644 --- a/Easy/Logger Rate Limiter.java +++ b/Easy/Logger Rate Limiter.java @@ -1,19 +1,16 @@ class Logger { - - /** Initialize your data structure here. */ - Map map; + + private final Map logger; + public Logger() { - map = new HashMap<>(); + this.logger = new HashMap<>(); } - /** Returns true if the message should be printed in the given timestamp, otherwise returns false. - If this method returns false, the message will not be printed. - The timestamp is in seconds granularity. */ public boolean shouldPrintMessage(int timestamp, String message) { - if (map.containsKey(message) && (timestamp - map.get(message)) < 10) { + if (this.logger.containsKey(message) && timestamp - this.logger.get(message) < 10) { return false; } - map.put(message, timestamp); + this.logger.put(message, timestamp); return true; } } diff --git a/Easy/Long Pressed Name.java b/Easy/Long Pressed Name.java index 48f9e787..3e134aa3 100644 --- a/Easy/Long Pressed Name.java +++ b/Easy/Long Pressed Name.java @@ -1,22 +1,27 @@ class Solution { public boolean isLongPressedName(String name, String typed) { - int nameIdx = 0; - int typeIdx = 0; - int nameLen = name.length(); - int typeLen = typed.length(); - while (nameIdx < nameLen && typeIdx < typeLen) { - if (name.charAt(nameIdx) != typed.charAt(typeIdx)) { + int idxName = 0; + int idxTyped = 0; + while (idxName < name.length() && idxTyped < typed.length()) { + if (name.charAt(idxName) != typed.charAt(idxTyped)) { return false; } - while (nameIdx < nameLen && typeIdx < typeLen && name.charAt(nameIdx) == typed.charAt(typeIdx)) { - nameIdx++; - typeIdx++; + char c = name.charAt(idxName); + int nameFreq = 0; + while (idxName < name.length() && name.charAt(idxName) == c) { + idxName++; + nameFreq++; } - char prev = name.charAt(nameIdx - 1); - while (typeIdx < typeLen && typed.charAt(typeIdx) == prev) { - typeIdx++; + c = typed.charAt(idxTyped); + int typedFreq = 0; + while (idxTyped < typed.length() && typed.charAt(idxTyped) == c) { + idxTyped++; + typedFreq++; + } + if (nameFreq > typedFreq) { + return false; } } - return nameIdx == nameLen && typeIdx == typeLen; + return idxName == name.length() && idxTyped == typed.length(); } } diff --git a/Easy/Longer Contiguous Segments of Ones than Zeros.java b/Easy/Longer Contiguous Segments of Ones than Zeros.java new file mode 100644 index 00000000..9a7d40c5 --- /dev/null +++ b/Easy/Longer Contiguous Segments of Ones than Zeros.java @@ -0,0 +1,22 @@ +class Solution { + public boolean checkZeroOnes(String s) { + int zeroBlock = 0; + int oneBlock = 0; + int idx = 0; + int n = s.length(); + while (idx < n) { + char c = s.charAt(idx); + int currCount = 0; + while (idx < n && s.charAt(idx) == c) { + currCount++; + idx++; + } + if (c == '0') { + zeroBlock = Math.max(zeroBlock, currCount); + } else { + oneBlock = Math.max(oneBlock, currCount); + } + } + return oneBlock > zeroBlock; + } +} diff --git a/Easy/Longest Alternating Subarray.java b/Easy/Longest Alternating Subarray.java new file mode 100644 index 00000000..65de425c --- /dev/null +++ b/Easy/Longest Alternating Subarray.java @@ -0,0 +1,21 @@ +class Solution { + public int alternatingSubarray(int[] nums) { + int start = 0; + int maxLength = -1; + int expectedDiff = 1; + for (int i = 1; i < nums.length;) { + if (nums[i] - nums[i - 1] != expectedDiff) { + if (nums[i] - nums[i - 1] != 1) { + i++; + } + start = i - 1; + expectedDiff = 1; + continue; + } + expectedDiff *= -1; + maxLength = Math.max(maxLength, i - start + 1); + i++; + } + return maxLength; + } +} diff --git a/Easy/Longest Common Prefix.java b/Easy/Longest Common Prefix.java index 49a0dc92..fb655701 100644 --- a/Easy/Longest Common Prefix.java +++ b/Easy/Longest Common Prefix.java @@ -1,30 +1,22 @@ class Solution { public String longestCommonPrefix(String[] strs) { - if (strs.length == 0) { - return ""; - } int minLength = Integer.MAX_VALUE; - int idx = -1; + int minLengthIdx = -1; for (int i = 0; i < strs.length; i++) { if (strs[i].length() < minLength) { minLength = strs[i].length(); - idx = i; + minLengthIdx = i; } } StringBuilder sb = new StringBuilder(); - for (int i = 0; i < strs[idx].length(); i++) { - boolean flag = true; + for (int i = 0; i < strs[minLengthIdx].length(); i++) { for (String str : strs) { - if (str.charAt(i) != strs[idx].charAt(i)) { - flag = false; - break; + if (str.charAt(i) != strs[minLengthIdx].charAt(i)) { + return sb.toString(); } } - if (!flag) { - break; - } - sb.append(strs[idx].charAt(i)); + sb.append(strs[minLengthIdx].charAt(i)); } return sb.toString(); - } + } } diff --git a/Easy/Longest Continuous Increasing Subsequence.java b/Easy/Longest Continuous Increasing Subsequence.java index 77d31e56..f0a73d6a 100644 --- a/Easy/Longest Continuous Increasing Subsequence.java +++ b/Easy/Longest Continuous Increasing Subsequence.java @@ -1,20 +1,16 @@ class Solution { public int findLengthOfLCIS(int[] nums) { - if (nums.length == 0) { - return 0; - } int maxLength = 1; - int currCount = 1; - int n = nums.length; - for (int i = 1; i < n; i++) { - if (nums[i] > nums[i - 1]) { - currCount++; - } - else { - maxLength = Math.max(maxLength, currCount); - currCount = 1; + int idx = 0; + while (idx < nums.length) { + int count = 1; + while (idx < nums.length && idx + 1 < nums.length && nums[idx] < nums[idx + 1]) { + idx++; + count++; } + maxLength = Math.max(maxLength, count); + idx++; } - return Math.max(maxLength, currCount); + return maxLength; } } diff --git a/Easy/Longest Even Odd Subarray With Threshold.java b/Easy/Longest Even Odd Subarray With Threshold.java new file mode 100644 index 00000000..f3dcc239 --- /dev/null +++ b/Easy/Longest Even Odd Subarray With Threshold.java @@ -0,0 +1,31 @@ +class Solution { + public int longestAlternatingSubarray(int[] nums, int threshold) { + int maxLength = 0; + int start = 0; + boolean evenRequired = true; + int idx = 0; + while (idx < nums.length) { + if (nums[idx] > threshold) { + idx++; + start = idx; + evenRequired = true; + continue; + } + if (nums[idx] % 2 == 0 && !evenRequired) { + start = idx; + evenRequired = true; + continue; + } + if (nums[idx] % 2 != 0 && evenRequired) { + idx++; + start = idx; + evenRequired = true; + continue; + } + idx++; + maxLength = Math.max(maxLength, idx - start); + evenRequired = !evenRequired; + } + return maxLength; + } +} diff --git a/Easy/Longest Harmonious Subsequence.java b/Easy/Longest Harmonious Subsequence.java index cd052aa8..73f54d43 100644 --- a/Easy/Longest Harmonious Subsequence.java +++ b/Easy/Longest Harmonious Subsequence.java @@ -1,15 +1,16 @@ class Solution { public int findLHS(int[] nums) { + int maxSubarraySize = 0; Map map = new HashMap<>(); for (int num : nums) { map.put(num, map.getOrDefault(num, 0) + 1); - } - int res = 0; - for (Integer key : map.keySet()) { - if (map.containsKey(key + 1)) { - res = Math.max(res, map.get(key) + map.get(key + 1)); + if (map.containsKey(num + 1)) { + maxSubarraySize = Math.max(maxSubarraySize, map.get(num) + map.get(num + 1)); + } + if (map.containsKey(num - 1)) { + maxSubarraySize = Math.max(maxSubarraySize, map.get(num) + map.get(num - 1)); } } - return res; + return maxSubarraySize; } } diff --git a/Easy/Longest Nice Substring.java b/Easy/Longest Nice Substring.java new file mode 100644 index 00000000..0795b833 --- /dev/null +++ b/Easy/Longest Nice Substring.java @@ -0,0 +1,14 @@ +class Solution { + public String longestNiceSubstring(String s) { + Set set = s.chars().mapToObj(c -> (char) c).collect(Collectors.toSet()); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (!(set.contains(Character.toLowerCase(c)) && set.contains(Character.toUpperCase(c)))) { + String left = longestNiceSubstring(s.substring(0, i)); + String right = longestNiceSubstring(s.substring(i + 1)); + return left.length() >= right.length() ? left : right; + } + } + return s; + } +} diff --git a/Easy/Longest Palindrome.java b/Easy/Longest Palindrome.java index 59688ba8..aa91e564 100644 --- a/Easy/Longest Palindrome.java +++ b/Easy/Longest Palindrome.java @@ -4,16 +4,15 @@ public int longestPalindrome(String s) { for (char c : s.toCharArray()) { map.put(c, map.getOrDefault(c, 0) + 1); } - int count = 0; + int totalLength = 0; boolean oddTaken = false; for (Character key : map.keySet()) { - int val = map.get(key); - count += (val / 2) * 2; - if ((val == 1 || val % 2 != 0) && !oddTaken) { - oddTaken = true; - count++; + totalLength += (map.get(key) / 2) * 2; + if (!oddTaken && map.get(key) % 2 != 0) { + totalLength++; + oddTaken = !oddTaken; } } - return count; + return totalLength; } } diff --git a/Easy/Longest Strictly Increasing or Strictly Decreasing Subarray.java b/Easy/Longest Strictly Increasing or Strictly Decreasing Subarray.java new file mode 100644 index 00000000..c1ed1c36 --- /dev/null +++ b/Easy/Longest Strictly Increasing or Strictly Decreasing Subarray.java @@ -0,0 +1,22 @@ +class Solution { + public int longestMonotonicSubarray(int[] nums) { + int max = 1; + int idx = 0; + int n = nums.length; + while (idx < n) { + if (idx == n - 1 || nums[idx + 1] == nums[idx]) { + idx++; + continue; + } + boolean increase = nums[idx + 1] > nums[idx]; + int start = idx; + while (idx + 1 < n && ( + (increase && nums[idx + 1] > nums[idx]) || + (!increase && nums[idx + 1] < nums[idx]))) { + idx++; + } + max = Math.max(max, idx - start + 1); + } + return max; + } +} diff --git a/Easy/Longest Subsequence With Limited Sum.java b/Easy/Longest Subsequence With Limited Sum.java new file mode 100644 index 00000000..5dd527a5 --- /dev/null +++ b/Easy/Longest Subsequence With Limited Sum.java @@ -0,0 +1,11 @@ +class Solution { + public int[] answerQueries(int[] nums, int[] queries) { + Arrays.sort(nums); + Arrays.parallelPrefix(nums, Integer::sum); + for (int i = 0; i < queries.length; i++) { + int idx = Arrays.binarySearch(nums, queries[i]); + queries[i] = Math.abs(idx + 1); + } + return queries; + } +} diff --git a/Easy/Lowest Common Ancestor of a Binary Search Tree.java b/Easy/Lowest Common Ancestor of a Binary Search Tree.java index aba618f7..d2a407b3 100644 --- a/Easy/Lowest Common Ancestor of a Binary Search Tree.java +++ b/Easy/Lowest Common Ancestor of a Binary Search Tree.java @@ -7,10 +7,11 @@ * TreeNode(int x) { val = x; } * } */ + class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { - if (root == null || p == null || q == null) { - return null; + if (root == null) { + return root; } if (root == p || root == q) { return root; @@ -18,11 +19,7 @@ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if ((root.val > p.val && root.val < q.val) || (root.val < p.val && root.val > q.val)) { return root; } - if (root.val > p.val && root.val > q.val) { - return lowestCommonAncestor(root.left, p, q); - } - else { - return lowestCommonAncestor(root.right, p, q); - } + TreeNode left = lowestCommonAncestor(root.left, p, q); + return left == null ? lowestCommonAncestor(root.right, p, q) : left; } } diff --git a/Easy/Majority Element.java b/Easy/Majority Element.java index 3c2b580c..0fc7be1d 100644 --- a/Easy/Majority Element.java +++ b/Easy/Majority Element.java @@ -1,13 +1,13 @@ class Solution { public int majorityElement(int[] nums) { + int majorityElement = nums[0]; int count = 0; - Integer candidate = null; for (int num : nums) { if (count == 0) { - candidate = num; + majorityElement = num; } - count += num == candidate ? 1 : -1; + count += num == majorityElement ? 1 : -1; } - return candidate; - } + return majorityElement; + } } diff --git a/Easy/Make Array Zero by Subtracting Equal Amounts.java b/Easy/Make Array Zero by Subtracting Equal Amounts.java new file mode 100644 index 00000000..304e3e92 --- /dev/null +++ b/Easy/Make Array Zero by Subtracting Equal Amounts.java @@ -0,0 +1,5 @@ +class Solution { + public int minimumOperations(int[] nums) { + return Arrays.stream(nums).boxed().filter(n -> n > 0).collect(Collectors.toSet()).size(); + } +} diff --git a/Easy/Make The String Great.java b/Easy/Make The String Great.java index a7cb7882..32b4684a 100644 --- a/Easy/Make The String Great.java +++ b/Easy/Make The String Great.java @@ -1,18 +1,24 @@ class Solution { - public String makeGood(String s) { - Stack stack = new Stack<>(); - for (char c : s.toCharArray()) { - if (!stack.isEmpty() && Math.abs(stack.peek() - c) == 32) { - stack.pop(); - } - else { - stack.push(c); - } + public String makeGood(String s) { + Stack stack = new Stack<>(); + for (char c : s.toCharArray()) { + if (!stack.isEmpty() && isBad(c, stack.peek())) { + stack.pop(); + continue; + } + stack.push(c); + } + StringBuilder sb = new StringBuilder(); + while (!stack.isEmpty()) { + sb.append(stack.pop()); + } + return sb.reverse().toString(); } - StringBuilder sb = new StringBuilder(); - while (!stack.isEmpty()) { - sb.append(stack.pop()); + + private static boolean isBad(char c1, char c2) { + if (c1 == c2) { + return false; + } + return Character.toLowerCase(c1) == Character.toLowerCase(c2); } - return sb.reverse().toString(); - } } diff --git a/Easy/Make Three Strings Equal.java b/Easy/Make Three Strings Equal.java new file mode 100644 index 00000000..a1e7477f --- /dev/null +++ b/Easy/Make Three Strings Equal.java @@ -0,0 +1,13 @@ +class Solution { + public int findMinimumOperations(String s1, String s2, String s3) { + int idx = 0; + while (idx < s1.length() && idx < s2.length() && idx < s3.length() && + s1.charAt(idx) == s2.charAt(idx) && s1.charAt(idx) == s3.charAt(idx)) { + idx++; + } + if (idx == 0) { + return -1; + } + return s1.length() + s2.length() + s3.length() - 3 * idx; + } +} diff --git a/Easy/Make Two Arrays Equal by Reversing Subarrays.java b/Easy/Make Two Arrays Equal by Reversing Subarrays.java new file mode 100644 index 00000000..62ce7dca --- /dev/null +++ b/Easy/Make Two Arrays Equal by Reversing Subarrays.java @@ -0,0 +1,18 @@ +class Solution { + public boolean canBeEqual(int[] target, int[] arr) { + Map map = new HashMap<>(); + for (int num : target) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + for (int num : arr) { + if (!map.containsKey(num)) { + return false; + } + map.put(num, map.get(num) - 1); + if (map.get(num) == 0) { + map.remove(num); + } + } + return map.isEmpty(); + } +} diff --git a/Easy/Make a Square with the Same Color.java b/Easy/Make a Square with the Same Color.java new file mode 100644 index 00000000..2f5524d8 --- /dev/null +++ b/Easy/Make a Square with the Same Color.java @@ -0,0 +1,40 @@ +class Solution { + + int[][] DIRS = {{0, 0}, {0, 1}, {1, 0}, {1, 1}}; + + public boolean canMakeSquare(char[][] grid) { + int rows = grid.length; + int cols = grid[0].length; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (isPossible(grid, i, j, rows, cols)) { + return true; + } + } + } + return false; + } + + private boolean isPossible(char[][] grid, int i, int j, int rows, int cols) { + int white = 0; + int black = 0; + int invalid = 0; + for (int[] dir : DIRS) { + int newX = i + dir[0]; + int newY = j + dir[1]; + if (newX >= 0 && newY >= 0 && newX < rows && newY < cols) { + white += grid[newX][newY] == 'W' ? 1 : 0; + black += grid[newX][newY] == 'B' ? 1 : 0; + } else { + invalid++; + } + } + if (invalid > 0) { + return false; + } + if (white == 4 || black == 4) { + return true; + } + return white == 1 || black == 1; + } +} diff --git a/Easy/Matrix Diagonal Sum.java b/Easy/Matrix Diagonal Sum.java index 772421b7..32e2a58f 100644 --- a/Easy/Matrix Diagonal Sum.java +++ b/Easy/Matrix Diagonal Sum.java @@ -1,21 +1,10 @@ class Solution { public int diagonalSum(int[][] mat) { + int n = mat.length; int sum = 0; - // Left -> Right Diagonal - for (int i = 0; i < mat.length; i++) { - sum += mat[i][i]; + for (int i = 0; i < n; i++) { + sum += mat[i][i] + mat[i][n - i - 1]; } - // Right -> Left Diagonal - int rowIdx = 0; - int colIdx = mat[0].length - 1; - while (rowIdx < mat.length) { - // Check to remove intersecting element in both diagonals - if (rowIdx != colIdx) { - sum += mat[rowIdx][colIdx]; - } - rowIdx++; - colIdx--; - } - return sum; + return sum - (n % 2 == 0 ? 0 : mat[n / 2][n / 2]); } } diff --git a/Easy/Matrix Similarity After Cyclic Shifts.java b/Easy/Matrix Similarity After Cyclic Shifts.java new file mode 100644 index 00000000..624bcf08 --- /dev/null +++ b/Easy/Matrix Similarity After Cyclic Shifts.java @@ -0,0 +1,17 @@ +class Solution { + public boolean areSimilar(int[][] mat, int k) { + for (int j = 0; j < mat.length; j++) { + if (j % 2 != 0) { + continue; + } + int[] row = mat[j]; + int n = row.length; + for (int i = 0; i < n; i++) { + if (row[i] != row[(i + k) % n]) { + return false; + } + } + } + return true; + } +} diff --git a/Easy/Max Area of Island.java b/Easy/Max Area of Island.java deleted file mode 100644 index cfd4e66c..00000000 --- a/Easy/Max Area of Island.java +++ /dev/null @@ -1,27 +0,0 @@ -class Solution { - int[][] dirs = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; - public int maxAreaOfIsland(int[][] grid) { - int m = grid.length; - int n = grid[0].length; - int maxArea = 0; - boolean[][] visited = new boolean[m][n]; - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - maxArea = Math.max(maxArea, helper(grid, i, j, m, n, visited)); - } - } - return maxArea; - } - - private int helper(int[][] grid, int i, int j, int m, int n, boolean[][] visited) { - if (i < 0 || i >= m || j < 0 || j >= n || visited[i][j] || grid[i][j] == 0) { - return 0; - } - int curr = 1; - visited[i][j] = true; - for (int[] dir : dirs) { - curr += helper(grid, i + dir[0], j + dir[1], m, n, visited); - } - return curr; - } -} diff --git a/Easy/Max Consecutive Ones.java b/Easy/Max Consecutive Ones.java index a9ef2478..6f3f557a 100644 --- a/Easy/Max Consecutive Ones.java +++ b/Easy/Max Consecutive Ones.java @@ -1,20 +1,16 @@ class Solution { - public int findMaxConsecutiveOnes(int[] nums) { - int i = 0; - int maxOnes = Integer.MIN_VALUE; - int temp = 0; - while (i < nums.length) { - if (nums[i] == 1) { - temp++; - } - else { - maxOnes = Math.max(maxOnes, temp); - temp = 0; - } - - i++; + public int findMaxConsecutiveOnes(int[] nums) { + int maxCount = 0; + for (int i = 0; i < nums.length; ) { + if (nums[i] == 1) { + int currIdx = i; + while (i < nums.length && nums[i] == 1) { + i++; } - - return Math.max(maxOnes, temp); + maxCount = Math.max(maxCount, i - currIdx); + } + i++; } + return maxCount; + } } diff --git a/Easy/Max Pair Sum in an Array.java b/Easy/Max Pair Sum in an Array.java new file mode 100644 index 00000000..e7f6332e --- /dev/null +++ b/Easy/Max Pair Sum in an Array.java @@ -0,0 +1,54 @@ +class Solution { + public int maxSum(int[] nums) { + Map map = new HashMap<>(); + for (int num : nums) { + int maxDigit = getMaxDigit(num); + if (!map.containsKey(maxDigit)) { + map.put(maxDigit, new Pair()); + } + map.get(maxDigit).record(num); + } + int result = -1; + for (Integer key : map.keySet()) { + result = Math.max(result, map.get(key).getPairSum()); + } + return result; + } + + private int getMaxDigit(int num) { + int maxDigit = 0; + while (num > 0) { + maxDigit = Math.max(maxDigit, num % 10); + num /= 10; + } + return maxDigit; + } + + private static class Pair { + int maximum; + int secondMaximum; + + public Pair() { + maximum = -1; + secondMaximum = -1; + } + + public void record(int num) { + if (maximum < num) { + if (secondMaximum < maximum) { + secondMaximum = maximum; + } + maximum = num; + } else if (secondMaximum < num) { + secondMaximum = num; + } + } + + public int getPairSum() { + if (maximum == -1 || secondMaximum == -1) { + return -1; + } + return maximum + secondMaximum; + } + } +} diff --git a/Easy/Max Stack.java b/Easy/Max Stack.java deleted file mode 100644 index 3125c3d0..00000000 --- a/Easy/Max Stack.java +++ /dev/null @@ -1,53 +0,0 @@ -class MaxStack { - - /** initialize your data structure here. */ - Stack stack; - Stack max; - public MaxStack() { - stack = new Stack<>(); - max = new Stack<>(); - } - - public void push(int x) { - stack.push(x); - max.push(max.isEmpty() ? x : Math.max(x, max.peek())); - } - - public int pop() { - max.pop(); - return stack.pop(); - } - - public int top() { - return stack.peek(); - } - - public int peekMax() { - return max.peek(); - } - - public int popMax() { - int num = max.peek(); - Stack temp = new Stack<>(); - while (stack.peek() != num) { - temp.push(stack.pop()); - max.pop(); - } - max.pop(); - stack.pop(); - while (!temp.isEmpty()) { - push(temp.pop()); - } - return num; - } -} - -/** - * Your MaxStack object will be instantiated and called as such: - * MaxStack obj = new MaxStack(); - * obj.push(x); - * int param_2 = obj.pop(); - * int param_3 = obj.top(); - * int param_4 = obj.peekMax(); - * int param_5 = obj.popMax(); - */ diff --git a/Easy/Maximize Distance to Closest Person.java b/Easy/Maximize Distance to Closest Person.java deleted file mode 100644 index a5d4d304..00000000 --- a/Easy/Maximize Distance to Closest Person.java +++ /dev/null @@ -1,23 +0,0 @@ -class Solution { - public int maxDistToClosest(int[] seats) { - int start = -1; - int max = 0; - int n = seats.length; - for (int i = 0; i < n; i++) { - if (seats[i] == 0) { - continue; - } - if (start == -1) { - max = Math.max(max, i); - } - else { - max = Math.max(max, (i - start) / 2); - } - start = i; - } - if (seats[n - 1] == 0) { - max = Math.max(max, n - 1 - start); - } - return max; - } -} diff --git a/Easy/Maximize Sum Of Array After K Negations.java b/Easy/Maximize Sum Of Array After K Negations.java new file mode 100644 index 00000000..12201a97 --- /dev/null +++ b/Easy/Maximize Sum Of Array After K Negations.java @@ -0,0 +1,16 @@ +class Solution { + public int largestSumAfterKNegations(int[] nums, int k) { + PriorityQueue pq = new PriorityQueue<>(); + int sum = 0; + for (int num : nums) { + pq.add(num); + sum += num; + } + while (k-- > 0) { + sum -= pq.peek(); + sum += -1 * pq.peek(); + pq.add(-1 * pq.poll()); + } + return sum; + } +} diff --git a/Easy/Maximum 69 Number.java b/Easy/Maximum 69 Number.java index a58d97e6..400bf663 100644 --- a/Easy/Maximum 69 Number.java +++ b/Easy/Maximum 69 Number.java @@ -1,23 +1,11 @@ class Solution { - public int maximum69Number (int num) { - int lastSixIndex = Integer.MAX_VALUE; - int count = 0; - int copy = num; - while (copy > 0) { - int rem = copy % 10; - if (rem == 6) { - lastSixIndex = count; - } - copy /= 10; - count++; + public int maximum69Number (int num) { + String numString = String.valueOf(num); + for (int i = 0; i < numString.length(); i++) { + if (numString.charAt(i) == '6') { + return Integer.parseInt(numString.substring(0, i) + '9' + numString.substring(i + 1)); + } + } + return num; } - if (lastSixIndex == Integer.MAX_VALUE) { - return num; - } - return ( - ((num / ((int) Math.pow(10, lastSixIndex + 1))) * ((int) Math.pow(10, lastSixIndex + 1))) + - (9 * ((int) Math.pow(10, lastSixIndex))) + - (num % ((int) Math.pow(10, lastSixIndex))) - ); - } } diff --git a/Easy/Maximum Ascending Subarray Sum.java b/Easy/Maximum Ascending Subarray Sum.java new file mode 100644 index 00000000..fd64c04c --- /dev/null +++ b/Easy/Maximum Ascending Subarray Sum.java @@ -0,0 +1,15 @@ +class Solution { + public int maxAscendingSum(int[] nums) { + int maxSum = 0; + int idx = 0; + int n = nums.length; + while (idx < n) { + int currSum = nums[idx++]; + while (idx < n && nums[idx] > nums[idx - 1]) { + currSum += nums[idx++]; + } + maxSum = Math.max(maxSum, currSum); + } + return maxSum; + } +} diff --git a/Easy/Maximum Average Subarray I.java b/Easy/Maximum Average Subarray I.java index 7ac37a5c..bdd6206e 100644 --- a/Easy/Maximum Average Subarray I.java +++ b/Easy/Maximum Average Subarray I.java @@ -1,17 +1,15 @@ class Solution { public double findMaxAverage(int[] nums, int k) { - Double max = null; double sum = 0; - for (int i = 0; i < k - 1; i++) { + for (int i = 0; i < k; i++) { sum += nums[i]; } - int start = 0; - for (int i = k - 1; i < nums.length; i++) { + double maxAverage = sum / k; + for (int i = k; i < nums.length; i++) { + sum -= nums[i - k]; sum += nums[i]; - double avg = sum / k; - max = max == null ? avg : Math.max(max, avg); - sum -= nums[start++]; + maxAverage = Math.max(maxAverage, sum / k); } - return max; + return maxAverage; } } diff --git a/Easy/Maximum Containers on a Ship.java b/Easy/Maximum Containers on a Ship.java new file mode 100644 index 00000000..e113027d --- /dev/null +++ b/Easy/Maximum Containers on a Ship.java @@ -0,0 +1,8 @@ +class Solution { + public int maxContainers(int n, int w, int maxWeight) { + if (n * n * w <= maxWeight) { + return n * n; + } + return maxWeight / w; + } +} diff --git a/Easy/Maximum Count of Positive Integer and Negative Integer.java b/Easy/Maximum Count of Positive Integer and Negative Integer.java new file mode 100644 index 00000000..73e0dba8 --- /dev/null +++ b/Easy/Maximum Count of Positive Integer and Negative Integer.java @@ -0,0 +1,11 @@ +class Solution { + public int maximumCount(int[] nums) { + int positiveCount = 0; + int negativeCount = 0; + for (int num : nums) { + positiveCount += num > 0 ? 1 : 0; + negativeCount += num < 0 ? 1 : 0; + } + return Math.max(positiveCount, negativeCount); + } +} diff --git a/Easy/Maximum Difference Between Even and Odd Frequency I.java b/Easy/Maximum Difference Between Even and Odd Frequency I.java new file mode 100644 index 00000000..ec68c06f --- /dev/null +++ b/Easy/Maximum Difference Between Even and Odd Frequency I.java @@ -0,0 +1,19 @@ +class Solution { + public int maxDifference(String s) { + Map map = new HashMap<>(); + for (char c : s.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); + } + int maxOdd = Integer.MIN_VALUE; + int minEven = Integer.MAX_VALUE; + for (Character key : map.keySet()) { + Integer value = map.get(key); + if (value % 2 == 0) { + minEven = Math.min(minEven, value); + } else { + maxOdd = Math.max(maxOdd, value); + } + } + return maxOdd - minEven; + } +} diff --git a/Easy/Maximum Difference Between Increasing Elements.java b/Easy/Maximum Difference Between Increasing Elements.java new file mode 100644 index 00000000..edb343d1 --- /dev/null +++ b/Easy/Maximum Difference Between Increasing Elements.java @@ -0,0 +1,13 @@ +class Solution { + public int maximumDifference(int[] nums) { + int currMin = nums[0]; + int maxDiff = -1; + for (int i = 0; i < nums.length; i++) { + currMin = Math.min(currMin, nums[i]); + if (nums[i] != currMin) { + maxDiff = Math.max(maxDiff, nums[i] - currMin); + } + } + return maxDiff; + } +} diff --git a/Easy/Maximum Difference by Remapping a Digit.java b/Easy/Maximum Difference by Remapping a Digit.java new file mode 100644 index 00000000..5241297f --- /dev/null +++ b/Easy/Maximum Difference by Remapping a Digit.java @@ -0,0 +1,25 @@ +class Solution { + public int minMaxDifference(int num) { + char digitsOne[] = String.valueOf(num).toCharArray(); + char digitsTwo[] = String.valueOf(num).toCharArray(); + char firstDigitOne = digitsOne[0]; + char firstDigitTwo = digitsOne[0]; + for (int i = 0; i < digitsOne.length; i++) { + if (digitsOne[i] != '9') { + firstDigitOne = digitsOne[i]; + break; + } + } + for (int i = 0; i < digitsOne.length; i++) { + if (digitsOne[i] == firstDigitOne) { + digitsOne[i] = '9'; + } + } + for(int i = 0; i < digitsOne.length; i++) { + if (digitsTwo[i] == firstDigitTwo) { + digitsTwo[i] = '0'; + } + } + return Integer.parseInt(String.valueOf(digitsOne)) - Integer.parseInt(String.valueOf(digitsTwo)); + } +} diff --git a/Easy/Maximum Distance in Arrays.java b/Easy/Maximum Distance in Arrays.java deleted file mode 100644 index 71a4581d..00000000 --- a/Easy/Maximum Distance in Arrays.java +++ /dev/null @@ -1,17 +0,0 @@ -class Solution { - public static int maxDistance(List> arrays) { - int min = arrays.get(0).get(0); - int max = arrays.get(0).get(arrays.get(0).size()-1); - int result = Integer.MIN_VALUE; - - for (int i=1; i map = new HashMap<>(); + int start = 0; + int end = 0; + int n = s.length(); + int result = 0; + while (end < n) { + map.put(s.charAt(end), map.getOrDefault(s.charAt(end), 0) + 1); + while (start <= end && map.get(s.charAt(end)) > 2) { + map.put(s.charAt(start), map.get(s.charAt(start)) - 1); + start++; + } + end++; + result = Math.max(result, end - start); + } + return result; + } +} diff --git a/Easy/Maximum Nesting Depth of the Parentheses.java b/Easy/Maximum Nesting Depth of the Parentheses.java new file mode 100644 index 00000000..8ce9eac2 --- /dev/null +++ b/Easy/Maximum Nesting Depth of the Parentheses.java @@ -0,0 +1,13 @@ +class Solution { + public int maxDepth(String s) { + int count = 0; + int result = 0; + for (char c : s.toCharArray()) { + if (c == '(' || c == ')') { + count += c == '(' ? 1 : -1; + } + result = Math.max(result, count); + } + return result; + } +} diff --git a/Easy/Maximum Number of Balloons.java b/Easy/Maximum Number of Balloons.java index b0553373..018f048c 100644 --- a/Easy/Maximum Number of Balloons.java +++ b/Easy/Maximum Number of Balloons.java @@ -1,15 +1,17 @@ class Solution { - public int maxNumberOfBalloons(String text) { - Map map = new HashMap<>(); - for (Character c : text.toCharArray()) { - map.put(c, map.getOrDefault(c, 0) + 1); - } - int maxCount = 0; - maxCount = map.getOrDefault('l', 0) / 2; - maxCount = Math.min(map.getOrDefault('o', 0) / 2, maxCount); - maxCount = Math.min(map.getOrDefault('b', 0), maxCount); - maxCount = Math.min(map.getOrDefault('a', 0), maxCount); - maxCount = Math.min(map.getOrDefault('n', 0), maxCount); - return maxCount; - } + public int maxNumberOfBalloons(String text) { + Map textFrequencyMap = getFrequencyMap(text); + Map ballonFrequencyMap = getFrequencyMap("balloon"); + return ballonFrequencyMap.keySet().stream() + .map(k -> + (int) (textFrequencyMap.getOrDefault(k, 0L) / ballonFrequencyMap.get(k))) + .min(Integer::compare) + .orElse(0); + } + + private Map getFrequencyMap(String s) { + return s.chars() + .mapToObj(c -> (char) c) + .collect(Collectors.groupingBy(Function.identity(), HashMap::new, Collectors.counting())); + } } diff --git a/Easy/Maximum Number of Balls in a Box.java b/Easy/Maximum Number of Balls in a Box.java new file mode 100644 index 00000000..1cde1b06 --- /dev/null +++ b/Easy/Maximum Number of Balls in a Box.java @@ -0,0 +1,21 @@ +class Solution { + public int countBalls(int lowLimit, int highLimit) { + Map map = new HashMap<>(); + int maxCount = 0; + for (int num = lowLimit; num <= highLimit; num++) { + int digitSum = getDigitSum(num); + map.put(digitSum, map.getOrDefault(digitSum, 0) + 1); + maxCount = Math.max(maxCount, map.get(digitSum)); + } + return maxCount; + } + + private int getDigitSum(int num) { + int sum = 0; + while (num > 0) { + sum += num % 10; + num /= 10; + } + return sum; + } +} diff --git a/Easy/Maximum Number of Operations With the Same Score I.java b/Easy/Maximum Number of Operations With the Same Score I.java new file mode 100644 index 00000000..22f6648d --- /dev/null +++ b/Easy/Maximum Number of Operations With the Same Score I.java @@ -0,0 +1,15 @@ +class Solution { + public int maxOperations(int[] nums) { + int score = -1; + int operations = 0; + for (int i = 0; i <= nums.length - 2; i += 2) { + int currScore = nums[i] + nums[i + 1]; + if (score != -1 && score != currScore) { + break; + } + score = currScore; + operations++; + } + return operations; + } +} diff --git a/Easy/Maximum Number of Pairs in Array.java b/Easy/Maximum Number of Pairs in Array.java new file mode 100644 index 00000000..38db03b0 --- /dev/null +++ b/Easy/Maximum Number of Pairs in Array.java @@ -0,0 +1,14 @@ +class Solution { + public int[] numberOfPairs(int[] nums) { + Map map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + int[] result = new int[2]; + for (Integer key : map.keySet()) { + result[0] += map.get(key) / 2; + result[1] += map.get(key) % 2; + } + return result; + } +} diff --git a/Easy/Maximum Number of Words Found in Sentences.java b/Easy/Maximum Number of Words Found in Sentences.java new file mode 100644 index 00000000..78b2af40 --- /dev/null +++ b/Easy/Maximum Number of Words Found in Sentences.java @@ -0,0 +1,6 @@ +class Solution { + public int mostWordsFound(String[] sentences) { + return Arrays.stream(sentences).map(sentence -> sentence.split("\\s").length) + .max(Integer::compare).orElse(0); + } +} diff --git a/Easy/Maximum Number of Words You Can Type.java b/Easy/Maximum Number of Words You Can Type.java new file mode 100644 index 00000000..dd3afc70 --- /dev/null +++ b/Easy/Maximum Number of Words You Can Type.java @@ -0,0 +1,9 @@ +class Solution { + public int canBeTypedWords(String text, String brokenLetters) { + return (int) Arrays.stream(text.split("\\s+")) + .filter(e -> e.chars() + .mapToObj(c -> (char) c) + .noneMatch(c -> brokenLetters.indexOf(c) != -1)) + .count(); + } +} diff --git a/Easy/Maximum Odd Binary Number.java b/Easy/Maximum Odd Binary Number.java new file mode 100644 index 00000000..861a3fd1 --- /dev/null +++ b/Easy/Maximum Odd Binary Number.java @@ -0,0 +1,13 @@ +class Solution { + public String maximumOddBinaryNumber(String s) { + int oneCount = 0; + for (char c : s.toCharArray()) { + oneCount += c == '1' ? 1 : 0; + } + if (oneCount == 0) { + return s; + } + int zeroCount = s.length() - oneCount; + return "1".repeat(oneCount - 1) + "0".repeat(zeroCount) + "1"; + } +} diff --git a/Easy/Maximum Population Year.java b/Easy/Maximum Population Year.java new file mode 100644 index 00000000..93766873 --- /dev/null +++ b/Easy/Maximum Population Year.java @@ -0,0 +1,15 @@ +class Solution { + public int maximumPopulation(int[][] logs) { + int[] population = new int[2051]; + for (int[] log : logs) { + population[log[0]]++; + population[log[1]]--; + } + int maxPopulationYear = 0; + for (int i = 1950; i <= 2050; i++) { + population[i] += population[i - 1]; + maxPopulationYear = population[i] > population[maxPopulationYear] ? i : maxPopulationYear; + } + return maxPopulationYear; + } +} diff --git a/Easy/Maximum Product Difference Between Two Pairs.java b/Easy/Maximum Product Difference Between Two Pairs.java new file mode 100644 index 00000000..3c3edf02 --- /dev/null +++ b/Easy/Maximum Product Difference Between Two Pairs.java @@ -0,0 +1,6 @@ +class Solution { + public int maxProductDifference(int[] nums) { + Arrays.sort(nums); + return nums[nums.length - 1] * nums[nums.length - 2] - nums[0] * nums[1]; + } +} diff --git a/Easy/Maximum Product of Three Numbers.java b/Easy/Maximum Product of Three Numbers.java new file mode 100644 index 00000000..981fbf96 --- /dev/null +++ b/Easy/Maximum Product of Three Numbers.java @@ -0,0 +1,9 @@ +class Solution { + public int maximumProduct(int[] nums) { + Arrays.sort(nums); + int n = nums.length; + int lastThree = nums[n - 1] * nums[n - 2] * nums[n - 3]; + int firstTwoAndLast = nums[0] * nums[1] * nums[n - 1]; + return Math.max(lastThree, firstTwoAndLast); + } +} diff --git a/Easy/Maximum Product of Two Digits.java b/Easy/Maximum Product of Two Digits.java new file mode 100644 index 00000000..c61f3c3a --- /dev/null +++ b/Easy/Maximum Product of Two Digits.java @@ -0,0 +1,17 @@ +class Solution { + public int maxProduct(int n) { + int maximum = Integer.MIN_VALUE; + int secondMaximum = Integer.MIN_VALUE; + while (n > 0) { + int num = n % 10; + n /= 10; + if (num > maximum) { + secondMaximum = maximum; + maximum = num; + } else if (num > secondMaximum) { + secondMaximum = num; + } + } + return maximum * secondMaximum; + } +} diff --git a/Easy/Maximum Product of three numbers.java b/Easy/Maximum Product of three numbers.java deleted file mode 100644 index ebc6f79b..00000000 --- a/Easy/Maximum Product of three numbers.java +++ /dev/null @@ -1,10 +0,0 @@ -class Solution { - public int maximumProduct(int[] nums) { - Arrays.sort(nums); - int n = nums.length; - int rightSideProd = nums[n - 1] * nums[n - 2] * nums[n - 3]; - int leftSideProd = nums[0] * nums[1] * nums[2]; - int mixedSideProd = nums[0] * nums[1] * nums[n - 1]; - return Math.max(rightSideProd, Math.max(leftSideProd, mixedSideProd)); - } -} diff --git a/Easy/Maximum Repeating Substring.java b/Easy/Maximum Repeating Substring.java new file mode 100644 index 00000000..9b1ae019 --- /dev/null +++ b/Easy/Maximum Repeating Substring.java @@ -0,0 +1,18 @@ +class Solution { + public int maxRepeating(String sequence, String word) { + int maxCount = 0; + int idx = 0; + int wordLength = word.length(); + int limitLength = sequence.length() - wordLength + 1; + while (idx < limitLength) { + int currCount = 0; + while (idx < limitLength && sequence.substring(idx, idx + wordLength).equals(word)) { + currCount++; + idx += wordLength; + } + maxCount = Math.max(maxCount, currCount); + idx++; + } + return maxCount; + } +} diff --git a/Easy/Maximum Score After Splitting a String.java b/Easy/Maximum Score After Splitting a String.java new file mode 100644 index 00000000..60649ebf --- /dev/null +++ b/Easy/Maximum Score After Splitting a String.java @@ -0,0 +1,17 @@ +class Solution { + public int maxScore(String s) { + int n = s.length(); + int ones = 0; + for (int i = 0; i < n; i++) { + ones += s.charAt(i) == '1' ? 1 : 0; + } + int score = 0; + int zeros = 0; + for (int i = 0; i < n - 1; i++) { + ones -= s.charAt(i) == '1' ? 1 : 0; + zeros += s.charAt(i) == '0' ? 1 : 0; + score = Math.max(score, zeros + ones); + } + return score; + } +} diff --git a/Easy/Maximum Subarray.java b/Easy/Maximum Subarray.java deleted file mode 100644 index 46b106c7..00000000 --- a/Easy/Maximum Subarray.java +++ /dev/null @@ -1,14 +0,0 @@ -class Solution { - public int maxSubArray(int[] nums) { - int currSum = 0; - int maxSum = Integer.MIN_VALUE; - for (int num : nums) { - currSum += num; - if (num > currSum) { - currSum = num; - } - maxSum = Math.max(maxSum, currSum); - } - return maxSum; - } -} diff --git a/Easy/Maximum Sum With Exactly K Elements.java b/Easy/Maximum Sum With Exactly K Elements.java new file mode 100644 index 00000000..ad738207 --- /dev/null +++ b/Easy/Maximum Sum With Exactly K Elements.java @@ -0,0 +1,13 @@ +class Solution { + public int maximizeSum(int[] nums, int k) { + int maxNum = 0; + for (int num : nums) { + maxNum = Math.max(num, maxNum); + } + int score = 0; + while (k-- > 0) { + score += maxNum++; + } + return score; + } +} diff --git a/Easy/Maximum Unique Subarray Sum After Deletion.java b/Easy/Maximum Unique Subarray Sum After Deletion.java new file mode 100644 index 00000000..e0a6a2ae --- /dev/null +++ b/Easy/Maximum Unique Subarray Sum After Deletion.java @@ -0,0 +1,17 @@ +class Solution { + public int maxSum(int[] nums) { + int max = nums[0]; + int sum = 0; + Set set = new HashSet<>(); + for (int num : nums) { + max = Math.max(num, max); + if (num > 0 && set.add(num)) { + sum += num; + } + } + if (max < 0) { + return max; + } + return sum; + } +} diff --git a/Easy/Maximum Units on a Truck.java b/Easy/Maximum Units on a Truck.java new file mode 100644 index 00000000..ce5198f0 --- /dev/null +++ b/Easy/Maximum Units on a Truck.java @@ -0,0 +1,15 @@ +class Solution { + public int maximumUnits(int[][] boxTypes, int truckSize) { + Arrays.sort(boxTypes, (o1, o2) -> o2[1] - o1[1]); + int maxUnits = 0; + for (int[] boxType : boxTypes) { + if (truckSize == 0) { + break; + } + int numberOfBoxesLoaded = Math.min(truckSize, boxType[0]); + maxUnits += numberOfBoxesLoaded * boxType[1]; + truckSize -= numberOfBoxesLoaded; + } + return maxUnits; + } +} diff --git a/Easy/Maximum Value of a String in an Array.java b/Easy/Maximum Value of a String in an Array.java new file mode 100644 index 00000000..29b0ec25 --- /dev/null +++ b/Easy/Maximum Value of a String in an Array.java @@ -0,0 +1,17 @@ +class Solution { + public int maximumValue(String[] strs) { + return Arrays.stream(strs) + .mapToInt(Solution::getStringValue) + .max() + .orElse(0); + } + + private static int getStringValue(String s) { + for (char c : s.toCharArray()) { + if (!Character.isDigit(c)) { + return s.length(); + } + } + return Integer.parseInt(s); + } +} diff --git a/Easy/Maximum Value of an Ordered Triplet I.java b/Easy/Maximum Value of an Ordered Triplet I.java new file mode 100644 index 00000000..870e4602 --- /dev/null +++ b/Easy/Maximum Value of an Ordered Triplet I.java @@ -0,0 +1,22 @@ +class Solution { + public long maximumTripletValue(int[] nums) { + int n = nums.length; + int[] maxLeft = new int[n]; + int[] maxRight = new int[n]; + maxLeft[0] = nums[0]; + for (int i = 1; i < n; i++) { + maxLeft[i] = Math.max(maxLeft[i - 1], nums[i]); + } + maxRight[n - 1] = nums[n - 1]; + for (int i = n - 2; i >= 0; i--) { + maxRight[i] = Math.max(maxRight[i + 1], nums[i]); + } + long maxValue = -1; + for (int i = 1; i < n - 1; i++) { + long left = (long) maxLeft[i - 1]; + long right = (long) maxRight[i + 1]; + maxValue = Math.max(maxValue, (left - nums[i]) * right); + } + return maxValue == -1 ? 0 : maxValue; + } +} diff --git a/Easy/Maximum depth of Binary tree.java b/Easy/Maximum depth of Binary tree.java index 98bfb842..8661d52e 100644 --- a/Easy/Maximum depth of Binary tree.java +++ b/Easy/Maximum depth of Binary tree.java @@ -4,14 +4,20 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public int maxDepth(TreeNode root) { - if (root == null) { - return 0; - } - return 1 + Math.max(maxDepth(root.left), maxDepth(root.right)); + public int maxDepth(TreeNode root) { + if (root == null) { + return 0; } + return 1 + Math.max(maxDepth(root.left), maxDepth(root.right)); + } } diff --git a/Easy/Mean of Array After Removing Some Elements.java b/Easy/Mean of Array After Removing Some Elements.java new file mode 100644 index 00000000..ef025364 --- /dev/null +++ b/Easy/Mean of Array After Removing Some Elements.java @@ -0,0 +1,10 @@ +class Solution { + public double trimMean(int[] arr) { + Arrays.sort(arr); + int n = arr.length; + double sum = 0; + for (int idx = n / 20; idx < n - n / 20; idx++) + sum += arr[idx]; + return sum / (n - n / 10); + } +} diff --git a/Easy/Meeting Rooms.java b/Easy/Meeting Rooms.java index 5b3b806c..53af36c7 100644 --- a/Easy/Meeting Rooms.java +++ b/Easy/Meeting Rooms.java @@ -1,30 +1,11 @@ -/** - * Definition for an interval. - * public class Interval { - * int start; - * int end; - * Interval() { start = 0; end = 0; } - * Interval(int s, int e) { start = s; end = e; } - * } - */ class Solution { - public static boolean canAttendMeetings(Interval[] intervals) { - Arrays.sort(intervals, new Comparator() { - @Override - public int compare(Interval o1, Interval o2) { - return o1.start - o2.start; - } - }); - - int i=0; - while (i < intervals.length - 1) { - if (intervals[i].end > intervals[i+1].start) { - return false; - } - - i++; - } - - return true; + public boolean canAttendMeetings(int[][] intervals) { + Arrays.sort(intervals, Comparator.comparingInt((int[] o) -> o[0])); + for (int i = 1; i < intervals.length; i++) { + if (intervals[i][0] < intervals[i - 1][1]) { + return false; + } } + return true; + } } diff --git a/Easy/Merge Similar Items.java b/Easy/Merge Similar Items.java new file mode 100644 index 00000000..d9f95996 --- /dev/null +++ b/Easy/Merge Similar Items.java @@ -0,0 +1,17 @@ +class Solution { + public List> mergeSimilarItems(int[][] items1, int[][] items2) { + Map map = new HashMap<>(); + for (int[] item : items1) { + map.put(item[0], map.getOrDefault(item[0], 0) + item[1]); + } + for (int[] item : items2) { + map.put(item[0], map.getOrDefault(item[0], 0) + item[1]); + } + List> result = new ArrayList<>(); + for (Integer key : map.keySet()) { + result.add(Arrays.asList(key, map.get(key))); + } + Collections.sort(result, Comparator.comparing(o -> o.get(0))); + return result; + } +} diff --git a/Easy/Merge Sorted Array.java b/Easy/Merge Sorted Array.java new file mode 100644 index 00000000..e99999f0 --- /dev/null +++ b/Easy/Merge Sorted Array.java @@ -0,0 +1,20 @@ +class Solution { + public void merge(int[] nums1, int m, int[] nums2, int n) { + int endIdxOne = m - 1; + int endIdxTwo = n - 1; + int currIdx = m + n - 1; + while (endIdxOne >= 0 || endIdxTwo >= 0) { + if (endIdxOne >= 0 && endIdxTwo >= 0) { + if (nums1[endIdxOne] > nums2[endIdxTwo]) { + nums1[currIdx--] = nums1[endIdxOne--]; + } else { + nums1[currIdx--] = nums2[endIdxTwo--]; + } + } else if (endIdxOne >= 0 && endIdxTwo < 0) { + nums1[currIdx--] = nums1[endIdxOne--]; + } else { + nums1[currIdx--] = nums2[endIdxTwo--]; + } + } + } +} diff --git a/Easy/Merge Sorted Arrays.java b/Easy/Merge Sorted Arrays.java deleted file mode 100644 index d734d76a..00000000 --- a/Easy/Merge Sorted Arrays.java +++ /dev/null @@ -1,25 +0,0 @@ -class Solution { - public void merge(int[] nums1, int m, int[] nums2, int n) { - int counter = m + n - 1; - int num1End = m - 1; - int num2End = n - 1; - while (num1End >= 0 || num2End >= 0) { - int val = -1; - if (num1End >= 0 && num2End >= 0) { - if (nums1[num1End] > nums2[num2End]) { - val = nums1[num1End--]; - } - else { - val = nums2[num2End--]; - } - } - else if (num1End >= 0 || num2End < 0) { - val = nums1[num1End--]; - } - else { - val = nums2[num2End--]; - } - nums1[counter--] = val; - } - } -} diff --git a/Easy/Merge Strings Alternately.java b/Easy/Merge Strings Alternately.java new file mode 100644 index 00000000..7b851597 --- /dev/null +++ b/Easy/Merge Strings Alternately.java @@ -0,0 +1,16 @@ +class Solution { + public String mergeAlternately(String word1, String word2) { + StringBuilder sb = new StringBuilder(); + int idxOne = 0; + int idxTwo = 0; + while (idxOne < word1.length() || idxTwo < word2.length()) { + if (idxOne < word1.length()) { + sb.append(word1.charAt(idxOne++)); + } + if (idxTwo < word2.length()) { + sb.append(word2.charAt(idxTwo++)); + } + } + return sb.toString(); + } +} diff --git a/Easy/Merge Two 2D Arrays by Summing Values.java b/Easy/Merge Two 2D Arrays by Summing Values.java new file mode 100644 index 00000000..87d07080 --- /dev/null +++ b/Easy/Merge Two 2D Arrays by Summing Values.java @@ -0,0 +1,27 @@ +class Solution { + public int[][] mergeArrays(int[][] nums1, int[][] nums2) { + int[] totalSum = new int[1001]; + int count = nums1.length; + for (int i = 0; i < nums1.length; i++) { + int id = nums1[i][0]; + int val = nums1[i][1]; + totalSum[id] = val; + } + for (int i = 0; i < nums2.length; i++) { + int id = nums2[i][0]; + int val = nums2[i][1]; + if (totalSum[id] == 0) { + count++; + } + totalSum[id] += val; + } + int[][] result = new int[count][2]; + int idx = 0; + for (int i = 1; i <= 1000; i++) { + if (totalSum[i] != 0) { + result[idx++] = new int[]{i, totalSum[i]}; + } + } + return result; + } +} diff --git a/Easy/Merge Two Sorted Lists.java b/Easy/Merge Two Sorted Lists.java index f4b4c5b5..e594a670 100644 --- a/Easy/Merge Two Sorted Lists.java +++ b/Easy/Merge Two Sorted Lists.java @@ -9,23 +9,29 @@ * } */ class Solution { - public ListNode mergeTwoLists(ListNode l1, ListNode l2) { - ListNode dummy = new ListNode(-1); - ListNode curr = dummy; - while (l1 != null || l2 != null) { - int val = Math.min( - (l1 == null ? Integer.MAX_VALUE : l1.val), - (l2 == null ? Integer.MAX_VALUE : l2.val) - ); - curr.next = new ListNode(val); - curr = curr.next; - if (l1 != null && l1.val == val) { - l1 = l1.next; - } - else { - l2 = l2.next; - } + public ListNode mergeTwoLists(ListNode l1, ListNode l2) { + ListNode dummy = new ListNode(); + ListNode curr = dummy; + while (l1 != null || l2 != null) { + int val = -1; + if (l1 != null && l2 != null) { + if (l1.val > l2.val) { + val = l2.val; + l2 = l2.next; + } else { + val = l1.val; + l1 = l1.next; + } + } else if (l1 != null && l2 == null) { + val = l1.val; + l1 = l1.next; + } else { + val = l2.val; + l2 = l2.next; + } + curr.next = new ListNode(val); + curr = curr.next; + } + return dummy.next; } - return dummy.next; - } } diff --git a/Easy/Merge two binary trees.java b/Easy/Merge two binary trees.java index d91c7643..1a487c2c 100644 --- a/Easy/Merge two binary trees.java +++ b/Easy/Merge two binary trees.java @@ -4,24 +4,24 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public TreeNode mergeTrees(TreeNode t1, TreeNode t2) { - if (t1 == null && t2 == null) { + public TreeNode mergeTrees(TreeNode root1, TreeNode root2) { + if (root1 == null && root2 == null) { return null; } - int val = (t1 == null ? 0 : t1.val) + (t2 == null ? 0 : t2.val); - TreeNode root = new TreeNode(val); - root.left = mergeTrees( - t1 == null ? null : t1.left, - t2 == null ? null : t2.left - ); - root.right = mergeTrees( - t1 == null ? null : t1.right, - t2 == null ? null : t2.right - ); + int value = (root1 == null ? 0 : root1.val) + (root2 == null ? 0 : root2.val); + TreeNode root = new TreeNode(value); + root.left = mergeTrees((root1 == null ? null : root1.left), (root2 == null ? null : root2.left)); + root.right = mergeTrees((root1 == null ? null : root1.right), (root2 == null ? null : root2.right)); return root; } } diff --git a/Easy/Min Cost Climbing Stairs.java b/Easy/Min Cost Climbing Stairs.java index 7a718918..1db8f19d 100644 --- a/Easy/Min Cost Climbing Stairs.java +++ b/Easy/Min Cost Climbing Stairs.java @@ -1,13 +1,12 @@ class Solution { - public int minCostClimbingStairs(int[] cost) { - int n = cost.length; - int first = cost[0]; - int second = cost[1]; - for (int i = 2; i < n; i++) { - int curr = cost[i] + Math.min(first, second); - first = second; - second = curr; + public int minCostClimbingStairs(int[] cost) { + int stepOneCost = cost[0]; + int stepTwoCost = cost[1]; + for (int i = 2; i < cost.length; i++) { + int currCost = cost[i] + Math.min(stepOneCost, stepTwoCost); + stepOneCost = stepTwoCost; + stepTwoCost = currCost; + } + return Math.min(stepOneCost, stepTwoCost); } - return Math.min(first, second); - } } diff --git a/Easy/Min Max Game.java b/Easy/Min Max Game.java new file mode 100644 index 00000000..f2405c20 --- /dev/null +++ b/Easy/Min Max Game.java @@ -0,0 +1,21 @@ +class Solution { + public int minMaxGame(int[] nums) { + Queue queue = new LinkedList<>(); + for (int num : nums) { + queue.add(num); + } + while (queue.size() > 1) { + int size = queue.size(); + boolean even = true; + for (int i = 0; i < size; i += 2) { + if (even) { + queue.add(Math.min(queue.remove(), queue.remove())); + } else { + queue.add(Math.max(queue.remove(), queue.remove())); + } + even = !even; + } + } + return queue.remove(); + } +} diff --git a/Easy/Min Stack.java b/Easy/Min Stack.java deleted file mode 100644 index 108f5e0c..00000000 --- a/Easy/Min Stack.java +++ /dev/null @@ -1,37 +0,0 @@ -class MinStack { - - /** initialize your data structure here. */ - Stack stack; - Stack min; - public MinStack() { - stack = new Stack<>(); - min = new Stack<>(); - } - - public void push(int x) { - stack.push(x); - min.push(Math.min(x, min.isEmpty() ? Integer.MAX_VALUE : min.peek())); - } - - public void pop() { - stack.pop(); - min.pop(); - } - - public int top() { - return stack.peek(); - } - - public int getMin() { - return min.peek(); - } -} - -/** - * Your MinStack object will be instantiated and called as such: - * MinStack obj = new MinStack(); - * obj.push(x); - * obj.pop(); - * int param_3 = obj.top(); - * int param_4 = obj.getMin(); - */ diff --git a/Easy/Minimize String Length.java b/Easy/Minimize String Length.java new file mode 100644 index 00000000..48d8ab26 --- /dev/null +++ b/Easy/Minimize String Length.java @@ -0,0 +1,7 @@ +class Solution { + public int minimizedStringLength(String s) { + return (int) s.chars() + .distinct() + .count(); + } +} diff --git a/Easy/Minimum Absolute Difference in BST.java b/Easy/Minimum Absolute Difference in BST.java index d29da542..80248dc1 100644 --- a/Easy/Minimum Absolute Difference in BST.java +++ b/Easy/Minimum Absolute Difference in BST.java @@ -14,24 +14,22 @@ * } */ class Solution { - int minDiff; - TreeNode prev; - public int getMinimumDifference(TreeNode root) { - minDiff = Integer.MAX_VALUE; - prev = null; - helper(root); - return minDiff; - } - - private void helper(TreeNode root) { - if (root == null) { - return; + public int getMinimumDifference(TreeNode root) { + List nodeValues = new ArrayList<>(); + inorder(root, nodeValues); + int minDifference = Integer.MAX_VALUE; + for (int i = 1; i < nodeValues.size(); i++) { + minDifference = Math.min(minDifference, nodeValues.get(i) - nodeValues.get(i - 1)); + } + return minDifference; } - helper(root.left); - if (prev != null) { - minDiff = Math.min(minDiff, Math.abs(root.val - prev.val)); + + private void inorder(TreeNode root, List nodeValues) { + if (root == null) { + return; + } + inorder(root.left, nodeValues); + nodeValues.add(root.val); + inorder(root.right, nodeValues); } - prev = root; - helper(root.right); - } } diff --git a/Easy/Minimum Absolute Difference.java b/Easy/Minimum Absolute Difference.java index c7204166..793dd171 100644 --- a/Easy/Minimum Absolute Difference.java +++ b/Easy/Minimum Absolute Difference.java @@ -1,19 +1,16 @@ class Solution { public List> minimumAbsDifference(int[] arr) { - List> list = new ArrayList<>(); int minDiff = Integer.MAX_VALUE; Arrays.sort(arr); for (int i = 0; i < arr.length - 1; i++) { - int diff = arr[i + 1] - arr[i]; - if (diff < minDiff) { - list.clear(); - list.add(Arrays.asList(arr[i], arr[i + 1])); - minDiff = diff; - } - else if (diff == minDiff) { - list.add(Arrays.asList(arr[i], arr[i + 1])); + minDiff = Math.min(minDiff, arr[i + 1] - arr[i]); + } + List> result = new ArrayList<>(); + for (int i = 0; i < arr.length - 1; i++) { + if (arr[i + 1] - arr[i] == minDiff) { + result.add(Arrays.asList(arr[i], arr[i + 1])); } } - return list; + return result; } } diff --git a/Easy/Minimum Amount of Time to Fill Cups.java b/Easy/Minimum Amount of Time to Fill Cups.java new file mode 100644 index 00000000..b772c001 --- /dev/null +++ b/Easy/Minimum Amount of Time to Fill Cups.java @@ -0,0 +1,25 @@ +class Solution { + public int fillCups(int[] amount) { + PriorityQueue pq = new PriorityQueue<>((a, b) -> b - a); + for (int count : amount) { + updateQueue(pq, count); + } + int totalTime = 0; + while (!pq.isEmpty()) { + int removedOne = pq.poll(); + int removedTwo = pq.isEmpty() ? 0 : pq.poll(); + removedOne--; + removedTwo--; + updateQueue(pq, removedOne); + updateQueue(pq, removedTwo); + totalTime++; + } + return totalTime; + } + + private void updateQueue(PriorityQueue pq, int count) { + if (count > 0) { + pq.add(count); + } + } +} diff --git a/Easy/Minimum Average of Smallest and Largest Elements.java b/Easy/Minimum Average of Smallest and Largest Elements.java new file mode 100644 index 00000000..f1fd9e2d --- /dev/null +++ b/Easy/Minimum Average of Smallest and Largest Elements.java @@ -0,0 +1,15 @@ +class Solution { + public double minimumAverage(int[] nums) { + double minAverage = Double.MAX_VALUE; + Arrays.sort(nums); + int left = 0; + int right = nums.length - 1; + while (left < right) { + double average = (nums[left] + nums[right]) / 2.0; + minAverage = Math.min(minAverage, average); + left++; + right--; + } + return minAverage; + } +} diff --git a/Easy/Minimum Bit Flips to Convert Number.java b/Easy/Minimum Bit Flips to Convert Number.java new file mode 100644 index 00000000..d3e2da78 --- /dev/null +++ b/Easy/Minimum Bit Flips to Convert Number.java @@ -0,0 +1,19 @@ +class Solution { + public int minBitFlips(int start, int goal) { + int numOfFlips = 0; + while (start > 0 && goal > 0) { + numOfFlips += start % 2 != goal % 2 ? 1 : 0; + start /= 2; + goal /= 2; + } + while (start > 0) { + numOfFlips += start % 2; + start /= 2; + } + while (goal > 0) { + numOfFlips += goal % 2; + goal /= 2; + } + return numOfFlips; + } +} diff --git a/Easy/Minimum Changes To Make Alternating Binary String.java b/Easy/Minimum Changes To Make Alternating Binary String.java new file mode 100644 index 00000000..95f9aaae --- /dev/null +++ b/Easy/Minimum Changes To Make Alternating Binary String.java @@ -0,0 +1,16 @@ +class Solution { + public int minOperations(String s) { + int startZero = 0; + int startOne = 0; + for (int i = 0; i < s.length(); i++) { + if (i % 2 == 0) { + startOne += s.charAt(i) == '0' ? 1 : 0; + startZero += s.charAt(i) == '1' ? 1 : 0; + } else { + startOne += s.charAt(i) == '1' ? 1 : 0; + startZero += s.charAt(i) == '0' ? 1 : 0; + } + } + return Math.min(startZero, startOne); + } +} diff --git a/Easy/Minimum Common Value.java b/Easy/Minimum Common Value.java new file mode 100644 index 00000000..5062e9a3 --- /dev/null +++ b/Easy/Minimum Common Value.java @@ -0,0 +1,16 @@ +class Solution { + public int getCommon(int[] nums1, int[] nums2) { + int idxOne = 0; + int idxTwo = 0; + while (idxOne < nums1.length && idxTwo < nums2.length) { + if (nums1[idxOne] < nums2[idxTwo]) { + idxOne++; + } else if (nums2[idxTwo] < nums1[idxOne]) { + idxTwo++; + } else { + return nums1[idxOne]; + } + } + return -1; + } +} diff --git a/Easy/Minimum Cost of Buying Candies With Discount.java b/Easy/Minimum Cost of Buying Candies With Discount.java new file mode 100644 index 00000000..71a2492b --- /dev/null +++ b/Easy/Minimum Cost of Buying Candies With Discount.java @@ -0,0 +1,19 @@ +class Solution { + public int minimumCost(int[] cost) { + PriorityQueue pq = new PriorityQueue<>((o1, o2) -> o2 - o1); + for (int price : cost) { + pq.add(price); + } + int totalCost = 0; + while (!pq.isEmpty()) { + totalCost += pq.poll(); + if (!pq.isEmpty()) { + totalCost += pq.poll(); + } + if (!pq.isEmpty()) { + pq.poll(); + } + } + return totalCost; + } +} diff --git a/Easy/Minimum Cost to Move Chips to The Same Position.java b/Easy/Minimum Cost to Move Chips to The Same Position.java new file mode 100644 index 00000000..7208148a --- /dev/null +++ b/Easy/Minimum Cost to Move Chips to The Same Position.java @@ -0,0 +1,14 @@ +class Solution { + public int minCostToMoveChips(int[] position) { + int evenCount = 0; + int oddCount = 0; + for (int p : position) { + if (p % 2 == 0) { + evenCount++; + } else { + oddCount++; + } + } + return Math.min(evenCount, oddCount); + } +} diff --git a/Easy/Minimum Cost to Reach Every Position.java b/Easy/Minimum Cost to Reach Every Position.java new file mode 100644 index 00000000..1b142d2c --- /dev/null +++ b/Easy/Minimum Cost to Reach Every Position.java @@ -0,0 +1,13 @@ +class Solution { + public int[] minCosts(int[] cost) { + int n = cost.length; + int[] result = new int[n]; + int minCost = Integer.MAX_VALUE; + for (int i = 0; i < n; i++) { + int curr = cost[i]; + minCost = Math.min(minCost, curr); + result[i] = minCost; + } + return result; + } +} diff --git a/Easy/Minimum Cuts to Divide a Circle.java b/Easy/Minimum Cuts to Divide a Circle.java new file mode 100644 index 00000000..16540797 --- /dev/null +++ b/Easy/Minimum Cuts to Divide a Circle.java @@ -0,0 +1,5 @@ +class Solution { + public int numberOfCuts(int n) { + return n == 1 ? 0 : (n % 2 == 0 ? n / 2 : n); + } +} diff --git a/Easy/Minimum Depth of a Binary Tree.java b/Easy/Minimum Depth of a Binary Tree.java index e1d21cc6..0da04114 100644 --- a/Easy/Minimum Depth of a Binary Tree.java +++ b/Easy/Minimum Depth of a Binary Tree.java @@ -14,31 +14,29 @@ * } */ class Solution { - public int minDepth(TreeNode root) { - if (root == null) { - return 0; - } - int steps = 1; - Queue queue = new LinkedList<>(); - queue.add(root); - while (!queue.isEmpty()) { - int size = queue.size(); - // Level iteration - while (size-- > 0) { - TreeNode removed = queue.remove(); - // Leaf reached - if (removed.left == null && removed.right == null) { - return steps; - } - if (removed.left != null) { - queue.add(removed.left); + public int minDepth(TreeNode root) { + if (root == null) { + return 0; } - if (removed.right != null) { - queue.add(removed.right); + int level = 1; + Queue queue = new LinkedList<>(); + queue.add(root); + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + TreeNode removed = queue.remove(); + if (removed.left == null && removed.right == null) { + return level; + } + if (removed.left != null) { + queue.add(removed.left); + } + if (removed.right != null) { + queue.add(removed.right); + } + } + level++; } - } - steps++; + return level; } - return steps; - } } diff --git a/Easy/Minimum Difference Between Highest and Lowest of K Scores.java b/Easy/Minimum Difference Between Highest and Lowest of K Scores.java new file mode 100644 index 00000000..e9b93530 --- /dev/null +++ b/Easy/Minimum Difference Between Highest and Lowest of K Scores.java @@ -0,0 +1,12 @@ +class Solution { + public int minimumDifference(int[] nums, int k) { + Arrays.sort(nums); + int left = 0; + int right = k - 1; + int minDiff = Integer.MAX_VALUE; + while (right < nums.length) { + minDiff = Math.min(minDiff, nums[right++] - nums[left++]); + } + return minDiff; + } +} diff --git a/Easy/Minimum Distance Between BST Nodes.java b/Easy/Minimum Distance Between BST Nodes.java index 4c147e39..af92feb0 100644 --- a/Easy/Minimum Distance Between BST Nodes.java +++ b/Easy/Minimum Distance Between BST Nodes.java @@ -14,25 +14,22 @@ * } */ class Solution { - Integer minDiff; - Integer prev; - public int minDiffInBST(TreeNode root) { - minDiff = Integer.MAX_VALUE; - prev = null; - helper(root); - return minDiff; - } - - private void helper(TreeNode root) { - if (root == null) { - return; + public int minDiffInBST(TreeNode root) { + int[] minDiff = {Integer.MAX_VALUE}; + Integer[] prevVal = {null}; + inorder(root, minDiff, prevVal); + return minDiff[0]; } - helper(root.left); - if (prev != null) { - minDiff = Math.min(minDiff, root.val - prev); + + private void inorder(TreeNode node, int[] minDiff, Integer[] prevValue) { + if (node == null) { + return; + } + inorder(node.left, minDiff, prevValue); + if (prevValue[0] != null) { + minDiff[0] = Math.min(minDiff[0], node.val - prevValue[0]); + } + prevValue[0] = node.val; + inorder(node.right, minDiff, prevValue); } - prev = root.val; - helper(root.right); - } } - diff --git a/Easy/Minimum Distance to the Target Element.java b/Easy/Minimum Distance to the Target Element.java new file mode 100644 index 00000000..e182a20d --- /dev/null +++ b/Easy/Minimum Distance to the Target Element.java @@ -0,0 +1,11 @@ +class Solution { + public int getMinDistance(int[] nums, int target, int start) { + int minDistance = Integer.MAX_VALUE; + for (int i = 0; i < nums.length; i++) { + if (nums[i] == target) { + minDistance = Math.min(minDistance, Math.abs(i - start)); + } + } + return minDistance; + } +} diff --git a/Easy/Minimum Hours of Training to Win a Competition.java b/Easy/Minimum Hours of Training to Win a Competition.java new file mode 100644 index 00000000..1e9f0c90 --- /dev/null +++ b/Easy/Minimum Hours of Training to Win a Competition.java @@ -0,0 +1,15 @@ +class Solution { + public int minNumberOfHours(int initialEnergy, int initialExperience, int[] energy, int[] experience) { + int totalEnergy = 0; + int experienceDeficit = 0; + for (int i = 0; i < energy.length; i++) { + totalEnergy += energy[i]; + if (initialExperience <= experience[i]) { + experienceDeficit += experience[i] - initialExperience + 1; + initialExperience = experience[i] + 1; + } + initialExperience += experience[i]; + } + return experienceDeficit + (totalEnergy >= initialEnergy ? totalEnergy - initialEnergy + 1 : 0); + } +} diff --git a/Easy/Minimum Index Sum of Two Lists.java b/Easy/Minimum Index Sum of Two Lists.java index 1a11f2d3..0333614d 100644 --- a/Easy/Minimum Index Sum of Two Lists.java +++ b/Easy/Minimum Index Sum of Two Lists.java @@ -4,25 +4,25 @@ public String[] findRestaurant(String[] list1, String[] list2) { for (int i = 0; i < list1.length; i++) { map.put(list1[i], i); } - List list = new ArrayList<>(); int minIndexSum = Integer.MAX_VALUE; + Map stringToIndexSum = new HashMap<>(); for (int i = 0; i < list2.length; i++) { if (map.containsKey(list2[i])) { - int indexSum = map.get(list2[i]) + i; - if (indexSum < minIndexSum) { - minIndexSum = indexSum; - list = new ArrayList<>(); - list.add(list2[i]); - } - else if (indexSum == minIndexSum) { - list.add(list2[i]); - } + int indexSum = i + map.get(list2[i]); + minIndexSum = Math.min(minIndexSum, indexSum); + stringToIndexSum.put(list2[i], indexSum); } } - String[] ans = new String[list.size()]; - for (int i = 0; i < list.size(); i++) { - ans[i] = list.get(i); + List result = new ArrayList<>(); + for (String key : stringToIndexSum.keySet()) { + if (stringToIndexSum.get(key) == minIndexSum) { + result.add(key); + } + } + String[] resultArr = new String[result.size()]; + for (int i = 0; i < result.size(); i++) { + resultArr[i] = result.get(i); } - return ans; + return resultArr; } } diff --git a/Easy/Minimum Moves to Convert String.java b/Easy/Minimum Moves to Convert String.java new file mode 100644 index 00000000..cc4cb2b2 --- /dev/null +++ b/Easy/Minimum Moves to Convert String.java @@ -0,0 +1,15 @@ +class Solution { + public int minimumMoves(String s) { + int numOfMoves = 0; + int idx = 0; + while (idx < s.length()) { + if (s.charAt(idx) == 'X') { + idx += 3; + numOfMoves++; + } else { + idx++; + } + } + return numOfMoves; + } +} diff --git a/Easy/Minimum Number Game.java b/Easy/Minimum Number Game.java new file mode 100644 index 00000000..a3377cb7 --- /dev/null +++ b/Easy/Minimum Number Game.java @@ -0,0 +1,11 @@ +class Solution { + public int[] numberGame(int[] nums) { + int[] result = new int[nums.length]; + Arrays.sort(nums); + for (int i = 0; i < nums.length; i += 2) { + result[i] = nums[i + 1]; + result[i + 1] = nums[i]; + } + return result; + } +} diff --git a/Easy/Minimum Number of Chairs in a Waiting Room.java b/Easy/Minimum Number of Chairs in a Waiting Room.java new file mode 100644 index 00000000..d7db8060 --- /dev/null +++ b/Easy/Minimum Number of Chairs in a Waiting Room.java @@ -0,0 +1,11 @@ +class Solution { + public int minimumChairs(String s) { + int requiredChairCount = 0; + int currChairCount = 0; + for (char c : s.toCharArray()) { + currChairCount += c == 'E' ? 1 : -1; + requiredChairCount = Math.max(requiredChairCount, currChairCount); + } + return requiredChairCount; + } +} diff --git a/Easy/Minimum Number of Moves to Seat Everyone.java b/Easy/Minimum Number of Moves to Seat Everyone.java new file mode 100644 index 00000000..be3f18c1 --- /dev/null +++ b/Easy/Minimum Number of Moves to Seat Everyone.java @@ -0,0 +1,11 @@ +class Solution { + public int minMovesToSeat(int[] seats, int[] students) { + Arrays.sort(seats); + Arrays.sort(students); + int moves = 0; + for (int i = 0; i < seats.length; i++) { + moves += Math.abs(seats[i] - students[i]); + } + return moves; + } +} diff --git a/Easy/Minimum Number of Operations to Convert Time.java b/Easy/Minimum Number of Operations to Convert Time.java new file mode 100644 index 00000000..8a5f1db2 --- /dev/null +++ b/Easy/Minimum Number of Operations to Convert Time.java @@ -0,0 +1,17 @@ +class Solution { + public int convertTime(String current, String correct) { + int minutesDiff = getMinutes(correct) - getMinutes(current); + int numOfOperations = 0; + int[] incrementFactors = {60, 15, 5, 1}; + for (int i = 0; i < incrementFactors.length; i++) { + numOfOperations += minutesDiff / incrementFactors[i]; + minutesDiff %= incrementFactors[i]; + } + return numOfOperations; + } + + private int getMinutes(String time) { + String[] split = time.split(":"); + return Integer.parseInt(split[0]) * 60 + Integer.parseInt(split[1]); + } +} diff --git a/Easy/Minimum Number of Operations to Make Elements in Array Distinct.java b/Easy/Minimum Number of Operations to Make Elements in Array Distinct.java new file mode 100644 index 00000000..a61239e7 --- /dev/null +++ b/Easy/Minimum Number of Operations to Make Elements in Array Distinct.java @@ -0,0 +1,18 @@ +class Solution { + public int minimumOperations(int[] nums) { + Set set = new HashSet<>(); + int index = -1; + for (int i = nums.length - 1; i >= 0; i--) { + if (set.contains(nums[i])) { + index = i; + break; + } + set.add(nums[i]); + } + if (index == -1) { + return 0; + } + index++; + return index % 3 == 0 ? index / 3 : (index / 3) + 1; + } +} diff --git a/Easy/Minimum Number of Pushes to Type Word I.java b/Easy/Minimum Number of Pushes to Type Word I.java new file mode 100644 index 00000000..0a6bbc24 --- /dev/null +++ b/Easy/Minimum Number of Pushes to Type Word I.java @@ -0,0 +1,14 @@ +class Solution { + public int minimumPushes(String word) { + int pushes = 0; + int idx = 0; + int multiple = 1; + while (idx < word.length()) { + int count = Math.min(8, word.length() - idx); + pushes += count * multiple; + multiple++; + idx += count; + } + return pushes; + } +} diff --git a/Easy/Minimum Operations to Collect Elements.java b/Easy/Minimum Operations to Collect Elements.java new file mode 100644 index 00000000..59e9d7c4 --- /dev/null +++ b/Easy/Minimum Operations to Collect Elements.java @@ -0,0 +1,16 @@ +class Solution { + public int minOperations(List nums, int k) { + boolean[] found = new boolean[k]; + int foundCount = 0; + for (int i = nums.size() - 1; i >= 0; i--) { + if (nums.get(i) <= k && !found[nums.get(i) - 1]) { + found[nums.get(i) - 1] = true; + foundCount++; + } + if (foundCount == k) { + return nums.size() - i; + } + } + return -1; + } +} diff --git a/Easy/Minimum Operations to Exceed Threshold Value I.java b/Easy/Minimum Operations to Exceed Threshold Value I.java new file mode 100644 index 00000000..6f792f07 --- /dev/null +++ b/Easy/Minimum Operations to Exceed Threshold Value I.java @@ -0,0 +1,15 @@ +class Solution { + public int minOperations(int[] nums, int k) { + Map map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + PriorityQueue pq = new PriorityQueue<>(); + pq.addAll(map.keySet()); + int count = 0; + while (!pq.isEmpty() && pq.peek() < k) { + count += map.get(pq.poll()); + } + return count; + } +} diff --git a/Easy/Minimum Operations to Make Array Sum Divisible by K.java b/Easy/Minimum Operations to Make Array Sum Divisible by K.java new file mode 100644 index 00000000..c941b50a --- /dev/null +++ b/Easy/Minimum Operations to Make Array Sum Divisible by K.java @@ -0,0 +1,9 @@ +class Solution { + public int minOperations(int[] nums, int k) { + int sum = 0; + for (int num : nums) { + sum += num; + } + return sum % k; + } +} diff --git a/Easy/Minimum Operations to Make the Array Increasing.java b/Easy/Minimum Operations to Make the Array Increasing.java new file mode 100644 index 00000000..99bdf2f7 --- /dev/null +++ b/Easy/Minimum Operations to Make the Array Increasing.java @@ -0,0 +1,15 @@ +class Solution { + public int minOperations(int[] nums) { + int prev = nums[0]; + int totalOperations = 0; + for (int i = 1; i < nums.length; i++) { + if (nums[i] <= prev) { + totalOperations += prev - nums[i] + 1; + prev++; + } else { + prev = nums[i]; + } + } + return totalOperations; + } +} diff --git a/Easy/Minimum Recolors to Get K Consecutive Black Blocks.java b/Easy/Minimum Recolors to Get K Consecutive Black Blocks.java new file mode 100644 index 00000000..596297cd --- /dev/null +++ b/Easy/Minimum Recolors to Get K Consecutive Black Blocks.java @@ -0,0 +1,17 @@ +class Solution { + public int minimumRecolors(String blocks, int k) { + int minRecolors = Integer.MAX_VALUE; + int blackBlockCount = 0; + for (int i = 0; i < k; i++) { + blackBlockCount += blocks.charAt(i) == 'W' ? 0 : 1; + } + int startIdx = 0; + for (int i = k; i < blocks.length(); i++) { + minRecolors = Math.min(minRecolors, k - blackBlockCount); + blackBlockCount += blocks.charAt(startIdx++) == 'W' ? 0 : -1; + blackBlockCount += blocks.charAt(i) == 'W' ? 0 : 1; + } + minRecolors = Math.min(minRecolors, k - blackBlockCount); + return minRecolors; + } +} diff --git a/Easy/Minimum Right Shifts to Sort the Array.java b/Easy/Minimum Right Shifts to Sort the Array.java new file mode 100644 index 00000000..aad801a0 --- /dev/null +++ b/Easy/Minimum Right Shifts to Sort the Array.java @@ -0,0 +1,19 @@ +class Solution { + public int minimumRightShifts(List nums) { + int mismatchIdx = -1; + int count = 0; + for (int i = 1; i < nums.size(); i++) { + if (nums.get(i - 1) > nums.get(i)) { + mismatchIdx = i; + count++; + } + } + if (count > 1) { + return -1; + } + if (count == 0) { + return 0; + } + return nums.get(nums.size() - 1) > nums.get(0) ? -1 : nums.size() - mismatchIdx; + } +} diff --git a/Easy/Minimum String Length After Removing Substrings.java b/Easy/Minimum String Length After Removing Substrings.java new file mode 100644 index 00000000..606d3394 --- /dev/null +++ b/Easy/Minimum String Length After Removing Substrings.java @@ -0,0 +1,15 @@ +class Solution { + public int minLength(String s) { + Stack stack = new Stack<>(); + for (char c : s.toCharArray()) { + if (!stack.isEmpty() && c == 'B' && stack.peek() == 'A') { + stack.pop(); + } else if (!stack.isEmpty() && c == 'D' && stack.peek() == 'C') { + stack.pop(); + } else { + stack.push(c); + } + } + return stack.size(); + } +} diff --git a/Easy/Minimum Sum of Four Digit Number After Splitting Digits.java b/Easy/Minimum Sum of Four Digit Number After Splitting Digits.java new file mode 100644 index 00000000..5929e314 --- /dev/null +++ b/Easy/Minimum Sum of Four Digit Number After Splitting Digits.java @@ -0,0 +1,11 @@ +class Solution { + public int minimumSum(int num) { + int[] digits = new int[4]; + for (int i = 0; i < 4; i++) { + digits[i] = num % 10; + num /= 10; + } + Arrays.sort(digits); + return (digits[0] * 10 + digits[2]) + (digits[1] * 10 + digits[3]); + } +} diff --git a/Easy/Minimum Sum of Mountain Triplets I.java b/Easy/Minimum Sum of Mountain Triplets I.java new file mode 100644 index 00000000..cabcd870 --- /dev/null +++ b/Easy/Minimum Sum of Mountain Triplets I.java @@ -0,0 +1,19 @@ +class Solution { + public int minimumSum(int[] nums) { + int n = nums.length; + int[] smallestRight = new int[n]; + smallestRight[n - 1] = nums[n - 1]; + for (int i = n - 2; i >= 0; i--) { + smallestRight[i] = Math.min(smallestRight[i + 1], nums[i]); + } + int smallestLeft = nums[0]; + int result = Integer.MAX_VALUE; + for (int i = 1; i < n; i++) { + if (smallestLeft < nums[i] && smallestRight[i] < nums[i]) { + result = Math.min(result, nums[i] + smallestRight[i] + smallestLeft); + } + smallestLeft = Math.min(smallestLeft, nums[i]); + } + return result == Integer.MAX_VALUE ? -1 : result; + } +} diff --git a/Easy/Minimum Time Visiting All Points.java b/Easy/Minimum Time Visiting All Points.java index 774ac97c..ee1a85b1 100644 --- a/Easy/Minimum Time Visiting All Points.java +++ b/Easy/Minimum Time Visiting All Points.java @@ -1,13 +1,17 @@ class Solution { - public int minTimeToVisitAllPoints(int[][] points) { - int time = 0; - for (int i = 1; i < points.length; i++) { - int[] prevPoint = points[i - 1]; - int[] currPoint = points[i]; - time += Math.max( - Math.abs(prevPoint[0] - currPoint[0]), Math.abs(prevPoint[1] - currPoint[1]) - ); + public int minTimeToVisitAllPoints(int[][] points) { + int time = 0; + int idx = 0; + while (idx < points.length - 1) { + time += calculateTime(points[idx], points[idx + 1]); + idx++; + } + return time; + } + + private static int calculateTime(int[] p1, int[] p2) { + int x = Math.abs(p1[0] - p2[0]); + int y = Math.abs(p1[1] - p2[1]); + return Math.max(x, y); } - return time; - } } diff --git a/Easy/Minimum Time to Type Word Using Special Typewriter.java b/Easy/Minimum Time to Type Word Using Special Typewriter.java new file mode 100644 index 00000000..e804f716 --- /dev/null +++ b/Easy/Minimum Time to Type Word Using Special Typewriter.java @@ -0,0 +1,12 @@ +class Solution { + public int minTimeToType(String word) { + int totalTime = 0; + char currentChar = 'a'; + for (char c : word.toCharArray()) { + int difference = Math.abs(c - currentChar); + totalTime += 1 + Math.min(difference, 26 - difference); + currentChar = c; + } + return totalTime; + } +} diff --git a/Easy/Minimum Value to Get Positive Step by Step Sum.java b/Easy/Minimum Value to Get Positive Step by Step Sum.java new file mode 100644 index 00000000..e8b91b93 --- /dev/null +++ b/Easy/Minimum Value to Get Positive Step by Step Sum.java @@ -0,0 +1,15 @@ +class Solution { + public int minStartValue(int[] nums) { + int startingValue = 1; + int currSum = 1; + for (int num : nums) { + if (currSum + num < 1) { + int diff = 1 - (currSum + num); + startingValue += diff; + currSum += diff; + } + currSum += num; + } + return startingValue; + } +} diff --git a/Easy/Missing Number.java b/Easy/Missing Number.java new file mode 100644 index 00000000..5d737295 --- /dev/null +++ b/Easy/Missing Number.java @@ -0,0 +1,11 @@ +class Solution { + public int missingNumber(int[] nums) { + int totalSum = 0; + for (int num : nums) { + totalSum += num; + } + int n = nums.length; + int expectedSum = (n * (n + 1)) / 2; + return expectedSum - totalSum; + } +} diff --git a/Easy/Missing Numbers.java b/Easy/Missing Numbers.java deleted file mode 100644 index 88e09784..00000000 --- a/Easy/Missing Numbers.java +++ /dev/null @@ -1,21 +0,0 @@ -public class Solution { - public int missingNumber(int[] nums) { - Arrays.sort(nums); - if (nums.length > 1 && nums[0] == 0) { - for (int i=0;i findMissingRanges(int[] nums, int lower, int upper) { + List ranges = new ArrayList<>(); + for (int i = 0; i < nums.length; i++) { + if (nums[i] < lower) { + continue; + } + if (nums[i] == lower) { + lower++; + continue; + } + ranges.add(getRange(lower, ( nums[i] - 1))); + lower = nums[i] + 1; + } + if (lower <= upper) { + ranges.add(getRange(lower, upper)); + } + return ranges; + } + + private String getRange(int down, int up) { + return down == up ? String.valueOf(up) : down + "->" + up; + } +} diff --git a/Easy/Modify the Matrix.java b/Easy/Modify the Matrix.java new file mode 100644 index 00000000..f238aa68 --- /dev/null +++ b/Easy/Modify the Matrix.java @@ -0,0 +1,16 @@ +class Solution { + public int[][] modifiedMatrix(int[][] matrix) { + int rows = matrix.length; + int cols = matrix[0].length; + for (int c = 0; c < cols; c++) { + int max = -1; + for (int r = 0; r < rows; r++) { + max = Math.max(max, matrix[r][c]); + } + for (int r = 0; r < rows; r++) { + matrix[r][c] = matrix[r][c] == -1 ? max : matrix[r][c]; + } + } + return matrix; + } +} diff --git a/Easy/Monotonic Array.java b/Easy/Monotonic Array.java index b9a44bcb..e460648c 100644 --- a/Easy/Monotonic Array.java +++ b/Easy/Monotonic Array.java @@ -1,25 +1,19 @@ class Solution { - public boolean isMonotonic(int[] A) { - if (A.length <= 1) { - return true; + public boolean isMonotonic(int[] nums) { + int idx = 0; + while (idx + 1 < nums.length && nums[idx] == nums[idx + 1]) { + idx++; + } + boolean increasing = idx + 1 < nums.length && nums[idx] < nums[idx + 1]; + while (idx + 1 < nums.length) { + if (nums[idx] > nums[idx + 1] && increasing) { + return false; + } + if (nums[idx] < nums[idx + 1] && !increasing) { + return false; + } + idx++; + } + return true; } - int dir = 0; - int idx = 0; - while (idx < A.length - 1 && dir == 0) { - dir = getDir(A, idx); - idx++; - } - while (idx < A.length - 1) { - int tempDir = getDir(A, idx); - if (tempDir != 0 && tempDir != dir) { - return false; - } - idx++; - } - return true; - } - - private int getDir(int[] A, int idx) { - return A[idx] < A[idx + 1] ? -1 : (A[idx] > A[idx + 1] ? 1 : 0); - } } diff --git a/Easy/Most Frequent Even Element.java b/Easy/Most Frequent Even Element.java new file mode 100644 index 00000000..75879d03 --- /dev/null +++ b/Easy/Most Frequent Even Element.java @@ -0,0 +1,23 @@ +class Solution { + public int mostFrequentEven(int[] nums) { + Map map = new HashMap<>(); + for (int num : nums) { + if (num % 2 == 0) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + } + int maxValue = 0; + int maxKey = -1; + for (Integer key : map.keySet()) { + if (map.get(key) >= maxValue) { + if (map.get(key) > maxValue) { + maxKey = key; + } else { + maxKey = Math.min(maxKey, key); + } + maxValue = map.get(key); + } + } + return maxKey; + } +} diff --git a/Easy/Most Frequent Number Following Key In an Array.java b/Easy/Most Frequent Number Following Key In an Array.java new file mode 100644 index 00000000..4f9b8523 --- /dev/null +++ b/Easy/Most Frequent Number Following Key In an Array.java @@ -0,0 +1,17 @@ +class Solution { + public int mostFrequent(int[] nums, int key) { + Map map = new HashMap<>(); + int maxCount = 0; + int maxCountCandidate = -1; + for (int i = 1; i < nums.length; i++) { + if (nums[i - 1] == key) { + map.put(nums[i], map.getOrDefault(nums[i], 0) + 1); + if (map.get(nums[i]) > maxCount) { + maxCount = map.get(nums[i]); + maxCountCandidate = nums[i]; + } + } + } + return maxCountCandidate; + } +} diff --git a/Easy/Move Zeroes.java b/Easy/Move Zeroes.java index 0406592c..acd2e2cb 100644 --- a/Easy/Move Zeroes.java +++ b/Easy/Move Zeroes.java @@ -1,17 +1,15 @@ class Solution { public void moveZeroes(int[] nums) { - int fast = 0; - int slow = 0; - int n = nums.length; - while (fast < n) { - if (nums[fast] != 0) { - nums[slow] = nums[fast]; - slow++; + int startIdx = 0; + int endIdx = 0; + while (endIdx < nums.length) { + if (nums[endIdx] != 0) { + nums[startIdx++] = nums[endIdx]; } - fast++; + endIdx++; } - while (slow < n) { - nums[slow++] = 0; + while (startIdx < nums.length) { + nums[startIdx++] = 0; } } } diff --git a/Easy/Moving Average from Data Stream.java b/Easy/Moving Average from Data Stream.java index 1c218cfb..ec9dca5b 100644 --- a/Easy/Moving Average from Data Stream.java +++ b/Easy/Moving Average from Data Stream.java @@ -1,23 +1,23 @@ class MovingAverage { - /** Initialize your data structure here. */ - Queue queue; - int size; - double sum; - public MovingAverage(int size) { - sum = 0; - this.size = size; - queue = new LinkedList<>(); - } - - public double next(int val) { - queue.add(val); - sum += val; - if (queue.size() > size) { - sum -= queue.remove(); + private final Queue queue; + private double currSum; + private final int size; + + public MovingAverage(int size) { + this.queue = new LinkedList<>(); + this.currSum = 0; + this.size = size; + } + + public double next(int val) { + this.queue.add(val); + this.currSum += val; + if (this.queue.size() > this.size) { + this.currSum -= this.queue.remove(); + } + return this.currSum / this.queue.size(); } - return sum / queue.size(); - } } /** diff --git a/Easy/N-Repeated Element in Size 2N Array.java b/Easy/N-Repeated Element in Size 2N Array.java index 07a2ddcc..f5ede891 100644 --- a/Easy/N-Repeated Element in Size 2N Array.java +++ b/Easy/N-Repeated Element in Size 2N Array.java @@ -1,11 +1,11 @@ class Solution { - public int repeatedNTimes(int[] A) { - int[] arr = new int[10001]; - for (int num : A) { - if (arr[num] == 1) { - return num; + public int repeatedNTimes(int[] nums) { + for (int i = 1; i <= 3; i++) { + for (int j = 0; j < nums.length - i; j++) { + if (nums[j] == nums[j + i]) { + return nums[j]; + } } - arr[num]++; } return -1; } diff --git a/Easy/N-ary Tree Level Order Traversal.java b/Easy/N-ary Tree Level Order Traversal.java deleted file mode 100644 index 11aac2e6..00000000 --- a/Easy/N-ary Tree Level Order Traversal.java +++ /dev/null @@ -1,42 +0,0 @@ -/* -// Definition for a Node. -class Node { - public int val; - public List children; - - public Node() {} - - public Node(int _val,List _children) { - val = _val; - children = _children; - } -}; -*/ -class Solution { - public List> levelOrder(Node root) { - List> values = new ArrayList<>(); - - if (root == null) { - return values; - } - - Queue queue = new LinkedList<>(); - queue.add(root); - - while (!queue.isEmpty()) { - int n = queue.size(); - List temp = new ArrayList<>(); - - while(n-- > 0) { - Node node = queue.remove(); - temp.add(node.val); - List childrens = node.children; - queue.addAll(childrens); - } - - values.add(temp); - } - - return values; - } -} diff --git a/Easy/N-ary Tree Postorder Traversal.java b/Easy/N-ary Tree Postorder Traversal.java index d0ba1138..3807c509 100644 --- a/Easy/N-ary Tree Postorder Traversal.java +++ b/Easy/N-ary Tree Postorder Traversal.java @@ -6,38 +6,31 @@ class Node { public Node() {} - public Node(int _val,List _children) { + public Node(int _val) { + val = _val; + } + + public Node(int _val, List _children) { val = _val; children = _children; } }; */ -class Solution { - public List postorder(Node root) { - List values = new ArrayList<>(); - if (root == null) { - return values; - } - - - Stack stack1 = new Stack<>(); - Stack stack2 = new Stack<>(); - stack1.push(root); - - while (!stack1.empty()) { - Node temp = stack1.pop(); - stack2.push(temp); - List childrens = temp.children; - for(Node children : childrens) { - stack1.push(children); - } - } - - while (!stack2.empty()) { - values.add(stack2.pop().val); - } - - return values; +class Solution { + public List postorder(Node root) { + List result = new ArrayList<>(); + helper(root, result); + return result; + } + + private void helper(Node root, List result) { + if (root == null) { + return; + } + for (Node child : root.children) { + helper(child, result); } + result.add(root.val); + } } diff --git a/Easy/N-ary Tree Preorder Traversal.java b/Easy/N-ary Tree Preorder Traversal.java index 73d61d32..49fac382 100644 --- a/Easy/N-ary Tree Preorder Traversal.java +++ b/Easy/N-ary Tree Preorder Traversal.java @@ -6,47 +6,33 @@ class Node { public Node() {} - public Node(int _val,List _children) { + public Node(int _val) { + val = _val; + } + + public Node(int _val, List _children) { val = _val; children = _children; } }; */ -class Solution { - List values = new ArrayList<>(); - public List preorder(Node root) { - updateListIterative(root); - return values; - } - - private void updateListIterative(Node root) { - if (root == null) { - return; - } - - Stack stack = new Stack<>(); - stack.push(root); - while (!stack.empty()) { - Node temp = stack.pop(); - values.add(temp.val); - - List childrens = temp.children; - - for (int i=childrens.size()-1; i>=0; i--) { - stack.push(childrens.get(i)); - } - } +class Solution { + public List preorder(Node root) { + if (root == null) { + return new ArrayList<>(); } - - private void updateListRecursive(Node root) { - if (root == null) { - return; - } - - values.add(root.val); - for (Node node : root.children) { - updateListRecursive(node); - } + List list = new ArrayList<>(); + Stack stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()) { + Node popped = stack.pop(); + list.add(popped.val); + List children = popped.children; + for (int i = children.size() - 1; i >= 0; i--) { + stack.push(children.get(i)); + } } + return list; + } } diff --git a/Easy/N-th Tribonacci Number.java b/Easy/N-th Tribonacci Number.java index cfaaeca9..23a53a62 100644 --- a/Easy/N-th Tribonacci Number.java +++ b/Easy/N-th Tribonacci Number.java @@ -1,17 +1,13 @@ class Solution { public int tribonacci(int n) { - int[] dp = new int[Math.max(n + 1, 3)]; - dp[0] = 0; - dp[1] = 1; - dp[2] = 1; - return helper(n, dp); - } - - private int helper(int n, int[] dp) { - if (n == 0 || dp[n] != 0) { - return dp[n]; + if (n <= 2) { + return n == 0 ? 0 : 1; + } + int[] dp = new int[n + 1]; + dp[1] = dp[2] = 1; + for (int i = 3; i <= n; i++) { + dp[i] = dp[i - 2] + dp[i - 1] + dp[i - 3]; } - dp[n] = helper(n - 1, dp) + helper(n - 2, dp) + helper(n - 3, dp); return dp[n]; } } diff --git a/Easy/Neither Minimum nor Maximum.java b/Easy/Neither Minimum nor Maximum.java new file mode 100644 index 00000000..b5d7a6d1 --- /dev/null +++ b/Easy/Neither Minimum nor Maximum.java @@ -0,0 +1,16 @@ +class Solution { + public int findNonMinOrMax(int[] nums) { + int min = nums[0]; + int max = nums[0]; + for (int num : nums) { + min = Math.min(num, min); + max = Math.max(num, max); + } + final int arrayMin = min; + final int arrayMax = max; + return Arrays.stream(nums) + .filter(num -> num != arrayMin && num != arrayMax) + .findFirst() + .orElse(-1); + } +} diff --git a/Easy/Nested List Weight Sum.java b/Easy/Nested List Weight Sum.java index 65fe828b..4a98107d 100644 --- a/Easy/Nested List Weight Sum.java +++ b/Easy/Nested List Weight Sum.java @@ -22,34 +22,33 @@ * public void add(NestedInteger ni); * * // @return the nested list that this NestedInteger holds, if it holds a nested list - * // Return null if this NestedInteger holds a single integer + * // Return empty list if this NestedInteger holds a single integer * public List getList(); * } */ class Solution { public int depthSum(List nestedList) { - int level = 1; Queue queue = new LinkedList<>(); - int sum = 0; + int currLevel = 1; for (NestedInteger nestedInteger : nestedList) { queue.add(nestedInteger); } + int totalSum = 0; while (!queue.isEmpty()) { int size = queue.size(); while (size-- > 0) { - NestedInteger nestedInteger = queue.remove(); - if (nestedInteger.isInteger()) { - sum += nestedInteger.getInteger() * level; - } - else { - List nList = nestedInteger.getList(); - for (NestedInteger nInteger : nList) { - queue.add(nInteger); + NestedInteger removed = queue.remove(); + if (removed.isInteger()) { + totalSum += currLevel * removed.getInteger(); + } else { + List nestedIntegers = removed.getList(); + for (NestedInteger nestedInteger : nestedIntegers) { + queue.add(nestedInteger); } } } - level++; + currLevel++; } - return sum; + return totalSum; } } diff --git a/Easy/Next Greater Element I.java b/Easy/Next Greater Element I.java index 8b7e88d1..35234857 100644 --- a/Easy/Next Greater Element I.java +++ b/Easy/Next Greater Element I.java @@ -1,20 +1,18 @@ class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) { - Stack stack = new Stack<>(); - int[] greater = new int[nums2.length]; Map map = new HashMap<>(); + Stack stack = new Stack<>(); for (int i = nums2.length - 1; i >= 0; i--) { - while (!stack.isEmpty() && stack.peek() < nums2[i]) { + while (!stack.isEmpty() && stack.peek() <= nums2[i]) { stack.pop(); } - greater[i] = stack.isEmpty() ? -1 : stack.peek(); - map.put(nums2[i], i); + map.put(nums2[i], stack.isEmpty() ? -1 : stack.peek()); stack.push(nums2[i]); } - int[] ans = new int[nums1.length]; + int[] result = new int[nums1.length]; for (int i = 0; i < nums1.length; i++) { - ans[i] = greater[map.get(nums1[i])]; + result[i] = map.getOrDefault(nums1[i], -1); } - return ans; + return result; } } diff --git a/Easy/Non-decreasing Array.java b/Easy/Non-decreasing Array.java deleted file mode 100644 index e6ce5b01..00000000 --- a/Easy/Non-decreasing Array.java +++ /dev/null @@ -1,20 +0,0 @@ -class Solution { - public boolean checkPossibility(int[] nums) { - Integer probIdx = null; - for (int i = 0; i < nums.length - 1; i++) { - if (nums[i] > nums[i + 1]) { - if (probIdx != null) { - return false; - } - probIdx = i; - } - } - return ( - probIdx == null || - probIdx == 0 || - probIdx == (nums.length - 2) || - nums[probIdx - 1] <= nums[probIdx + 1] || - nums[probIdx] <= nums[probIdx + 2] - ); - } -} diff --git a/Easy/Number Of Rectangles That Can Form The Largest Square.java b/Easy/Number Of Rectangles That Can Form The Largest Square.java new file mode 100644 index 00000000..3368c00f --- /dev/null +++ b/Easy/Number Of Rectangles That Can Form The Largest Square.java @@ -0,0 +1,12 @@ +class Solution { + public int countGoodRectangles(int[][] rectangles) { + int maxSquareSide = 0; + Map map = new HashMap<>(); + for (int[] rectangle : rectangles) { + int currSquareSide = Math.min(rectangle[0], rectangle[1]); + map.put(currSquareSide, map.getOrDefault(currSquareSide, 0) + 1); + maxSquareSide = Math.max(maxSquareSide, currSquareSide); + } + return map.get(maxSquareSide); + } +} diff --git a/Easy/Number of Arithmetic Triplets.java b/Easy/Number of Arithmetic Triplets.java new file mode 100644 index 00000000..8094d932 --- /dev/null +++ b/Easy/Number of Arithmetic Triplets.java @@ -0,0 +1,13 @@ +class Solution { + public int arithmeticTriplets(int[] nums, int diff) { + int count = 0; + Set set = new HashSet<>(); + for (int num : nums) { + if (set.contains(num - diff) && set.contains(num - 2 * diff)) { + count++; + } + set.add(num); + } + return count; + } +} diff --git a/Easy/Number of Beautiful Pairs.java b/Easy/Number of Beautiful Pairs.java new file mode 100644 index 00000000..2993a81e --- /dev/null +++ b/Easy/Number of Beautiful Pairs.java @@ -0,0 +1,29 @@ +class Solution { + public int countBeautifulPairs(int[] nums) { + int pairCount = 0; + for (int i = 0; i < nums.length; i++) { + int lastDigit = nums[i] % 10; + for (int j = 0; j < i; j++) { + int firstDigit = getFirstDigit(nums[j]); + pairCount += gcd(firstDigit, lastDigit) == 1 ? 1 : 0; + } + } + return pairCount; + } + + private static int getFirstDigit(int num) { + while (num >= 10) { + num /= 10; + } + return num; + } + + private static int gcd(int a, int b) { + while (b != 0) { + int temp = a % b; + a = b; + b = temp; + } + return a; + } +} diff --git a/Easy/Number of Changing Keys.java b/Easy/Number of Changing Keys.java new file mode 100644 index 00000000..bb6bc939 --- /dev/null +++ b/Easy/Number of Changing Keys.java @@ -0,0 +1,11 @@ +class Solution { + public int countKeyChanges(String s) { + int changes = 0; + for (int i = 1; i < s.length(); i++) { + if (Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(i - 1))) { + changes++; + } + } + return changes; + } +} diff --git a/Easy/Number of Common Factors.java b/Easy/Number of Common Factors.java new file mode 100644 index 00000000..4ecdf04e --- /dev/null +++ b/Easy/Number of Common Factors.java @@ -0,0 +1,12 @@ +class Solution { + public int commonFactors(int a, int b) { + int count = 0; + int minNum = Math.min(a, b); + for (int i = 1; i <= minNum / 2; i++) { + if (a % i == 0 && b % i == 0) { + count++; + } + } + return count + (a % minNum == 0 && b % minNum == 0 ? 1 : 0); + } +} diff --git a/Easy/Number of Different Integers in a String.java b/Easy/Number of Different Integers in a String.java new file mode 100644 index 00000000..3cdd6557 --- /dev/null +++ b/Easy/Number of Different Integers in a String.java @@ -0,0 +1,18 @@ +class Solution { + public int numDifferentIntegers(String word) { + Set set = new HashSet<>(); + int idx = 0; + int n = word.length(); + while (idx < n) { + if (Character.isDigit(word.charAt(idx))) { + int num = 0; + while (idx < n && Character.isDigit(word.charAt(idx))) { + num = num * 10 + Character.getNumericValue(word.charAt(idx++)); + } + set.add(num); + } + idx++; + } + return set.size(); + } +} diff --git a/Easy/Number of Distinct Averages.java b/Easy/Number of Distinct Averages.java new file mode 100644 index 00000000..cb2f9b34 --- /dev/null +++ b/Easy/Number of Distinct Averages.java @@ -0,0 +1,13 @@ +class Solution { + public int distinctAverages(int[] nums) { + Arrays.sort(nums); + Set averages = new HashSet<>(); + int startIdx = 0; + int endIdx = nums.length - 1; + while (startIdx <= endIdx) { + double total = (double) (nums[startIdx++] + nums[endIdx--]); + averages.add(total / 2); + } + return averages.size(); + } +} diff --git a/Easy/Number of Employees Who Met the Target.java b/Easy/Number of Employees Who Met the Target.java new file mode 100644 index 00000000..64f20287 --- /dev/null +++ b/Easy/Number of Employees Who Met the Target.java @@ -0,0 +1,5 @@ +class Solution { + public int numberOfEmployeesWhoMetTarget(int[] hours, int target) { + return (int) Arrays.stream(hours).filter(hour -> hour >= target).count(); + } +} diff --git a/Easy/Number of Equivalent Domino Pairs.java b/Easy/Number of Equivalent Domino Pairs.java index 718169ae..422b51e2 100644 --- a/Easy/Number of Equivalent Domino Pairs.java +++ b/Easy/Number of Equivalent Domino Pairs.java @@ -1,23 +1,12 @@ class Solution { public int numEquivDominoPairs(int[][] dominoes) { - int count = 0; - Map map = new HashMap<>(); - for (int i = 0; i < dominoes.length; i++) { - String straightKey = dominoes[i][0] + "/" + dominoes[i][1]; - String revKey = dominoes[i][1] + "/" + dominoes[i][0]; - if (map.containsKey(straightKey)) { - count += map.get(straightKey); - } - else if (!straightKey.equals(revKey)) { - if (map.containsKey(revKey)) { - count += map.get(revKey); - } - } - map.put(straightKey, map.getOrDefault(straightKey, 0) + 1); - if (dominoes[i][0] != dominoes[i][1]) { - map.put(revKey, map.getOrDefault(revKey, 0) + 1); - } + int numOfPairs = 0; + Map map = new HashMap<>(); + for (int[] dominoe : dominoes) { + int key = Math.min(dominoe[0], dominoe[1]) * 10 + Math.max(dominoe[0], dominoe[1]); + numOfPairs += map.getOrDefault(key, 0); + map.put(key, map.getOrDefault(key, 0) + 1); } - return count; + return numOfPairs; } } diff --git a/Easy/Number of Good Pairs.java b/Easy/Number of Good Pairs.java index d3c347af..edb3a754 100644 --- a/Easy/Number of Good Pairs.java +++ b/Easy/Number of Good Pairs.java @@ -1,11 +1,11 @@ class Solution { - public int numIdenticalPairs(int[] nums) { - Map map = new HashMap<>(); - int count = 0; - for (int num : nums) { - count += map.getOrDefault(num, 0); - map.put(num, map.getOrDefault(num, 0) + 1); + public int numIdenticalPairs(int[] nums) { + Map map = new HashMap<>(); + int count = 0; + for (int num : nums) { + count += map.getOrDefault(num, 0); + map.put(num, map.getOrDefault(num, 0) + 1); + } + return count; } - return count; - } } diff --git a/Easy/Number of Recent Calls.java b/Easy/Number of Recent Calls.java index 230dc7be..4b039208 100644 --- a/Easy/Number of Recent Calls.java +++ b/Easy/Number of Recent Calls.java @@ -1,16 +1,16 @@ class RecentCounter { - Queue queue; - int limit; + + private Queue queue; + public RecentCounter() { queue = new LinkedList<>(); - limit = 3000; } public int ping(int t) { - queue.add(t); - while (!queue.isEmpty() && ((t - queue.peek()) > limit)) { + while (!queue.isEmpty() && t - queue.peek() > 3000) { queue.remove(); } + queue.add(t); return queue.size(); } } diff --git a/Easy/Number of Senior Citizens.java b/Easy/Number of Senior Citizens.java new file mode 100644 index 00000000..cb658ee0 --- /dev/null +++ b/Easy/Number of Senior Citizens.java @@ -0,0 +1,8 @@ +class Solution { + public int countSeniors(String[] details) { + return (int) Arrays.stream(details) + .map(s -> Integer.parseInt(s.substring(11, 13))) + .filter(age -> age > 60) + .count(); + } +} diff --git a/Easy/Number of Strings That Appear as Substrings in Word.java b/Easy/Number of Strings That Appear as Substrings in Word.java new file mode 100644 index 00000000..f328158d --- /dev/null +++ b/Easy/Number of Strings That Appear as Substrings in Word.java @@ -0,0 +1,5 @@ +class Solution { + public int numOfStrings(String[] patterns, String word) { + return (int) Arrays.stream(patterns).filter(p -> word.contains(p)).count(); + } +} diff --git a/Easy/Number of Students Unable to Eat Lunch.java b/Easy/Number of Students Unable to Eat Lunch.java new file mode 100644 index 00000000..3902c4c1 --- /dev/null +++ b/Easy/Number of Students Unable to Eat Lunch.java @@ -0,0 +1,13 @@ +class Solution { + public int countStudents(int[] students, int[] sandwiches) { + int[] preferenceCount = new int[2]; + for (int preference : students) { + preferenceCount[preference]++; + } + int i = 0; + for (i = 0; i < sandwiches.length && preferenceCount[sandwiches[i]] > 0; i++) { + preferenceCount[sandwiches[i]]--; + } + return sandwiches.length - i; + } +} diff --git a/Easy/Number of Unequal Triplets in Array.java b/Easy/Number of Unequal Triplets in Array.java new file mode 100644 index 00000000..fc2fa82a --- /dev/null +++ b/Easy/Number of Unequal Triplets in Array.java @@ -0,0 +1,17 @@ +class Solution { + public int unequalTriplets(int[] nums) { + Map map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + int result = 0; + int left = 0; + int right = nums.length; + for (Integer key : map.keySet()) { + right -= map.get(key); + result += left * map.get(key) * right; + left += map.get(key); + } + return result; + } +} diff --git a/Easy/Number of Valid Words in a Sentence.java b/Easy/Number of Valid Words in a Sentence.java new file mode 100644 index 00000000..686add3b --- /dev/null +++ b/Easy/Number of Valid Words in a Sentence.java @@ -0,0 +1,35 @@ +class Solution { + + public int countValidWords(String sentence) { + return (int) Arrays.stream(sentence.split("\\s+")).filter(Solution::isValidWord).count(); + } + + public static boolean isValidWord(String s) { + if (s.isEmpty() + || s.charAt(0) == '-' + || s.charAt(s.length() - 1) == '-' + || (s.length() > 1 && !Character.isLetter(s.charAt(0)))) { + return false; + } + boolean punctuationFound = false; + boolean hyphenFound = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (Character.isDigit(c)) { + return false; + } + if (c == '-') { + if (hyphenFound || !(Character.isLetter(s.charAt(i - 1)) && Character.isLetter(s.charAt(i + 1)))) { + return false; + } + hyphenFound = true; + } else if (!Character.isLetter(c)) { + if (punctuationFound || i != s.length() - 1) { + return false; + } + punctuationFound = true; + } + } + return true; + } +} diff --git a/Easy/Number of segments in a String.java b/Easy/Number of segments in a String.java index 1ecd407e..2139e560 100644 --- a/Easy/Number of segments in a String.java +++ b/Easy/Number of segments in a String.java @@ -1,14 +1,11 @@ class Solution { - public int countSegments(String str) { - String[] arr = str.split("\\s+"); - - int count = 0; - for (String s : arr) { - if ((!s.equals("\\s+")) && s.length() > 0) { - count++; - } - } - - return count; + public int countSegments(String s) { + int count = 0; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) != ' ' && (i == 0 || s.charAt(i - 1) == ' ')) { + count++; + } } + return count; + } } diff --git a/Easy/Odd String Difference.java b/Easy/Odd String Difference.java new file mode 100644 index 00000000..d6fa4b49 --- /dev/null +++ b/Easy/Odd String Difference.java @@ -0,0 +1,23 @@ +class Solution { + public String oddString(String[] words) { + Map> diffCounter = new HashMap<>(); + for (String word : words) { + String key = getDiffCounter(word); + diffCounter.computeIfAbsent(key, k -> new HashSet<>()).add(word); + } + for (String key : diffCounter.keySet()) { + if (diffCounter.get(key).size() == 1) { + return diffCounter.get(key).iterator().next(); + } + } + return ""; + } + + private static String getDiffCounter(String word) { + StringBuilder sb = new StringBuilder(); + for (int i = 1; i < word.length(); i++) { + sb.append(word.charAt(i) - word.charAt(i - 1)).append('|'); + } + return sb.toString(); + } +} diff --git a/Easy/Paint Fence.java b/Easy/Paint Fence.java deleted file mode 100644 index 72ea89e6..00000000 --- a/Easy/Paint Fence.java +++ /dev/null @@ -1,12 +0,0 @@ -class Solution { - public int numWays(int n, int k) { - int[] ways = new int[Math.max(n + 1, 3)]; - ways[0] = 0; - ways[1] = k; - ways[2] = k * k; - for (int i = 3; i <= n; i++) { - ways[i] = (ways[i - 1] * (k - 1)) + (ways[i - 2] * (k - 1)); - } - return ways[n]; - } -} diff --git a/Easy/Paint House.java b/Easy/Paint House.java deleted file mode 100644 index 797243d2..00000000 --- a/Easy/Paint House.java +++ /dev/null @@ -1,18 +0,0 @@ -class Solution { - public int minCost(int[][] costs) { - if (costs.length == 0) { - return 0; - } - - for (int i=1; i map = new HashMap<>(); int count = 0; for (int t : time) { - if (map.containsKey(((60 - t % 60)) % 60)) { - count += map.get((60 - t % 60) % 60); - } + count += map.getOrDefault((60 - t % 60) % 60, 0); map.put(t % 60, map.getOrDefault(t % 60, 0) + 1); } return count; diff --git a/Easy/Palindrome Linked List.java b/Easy/Palindrome Linked List.java index 33fcc9f4..11c23754 100644 --- a/Easy/Palindrome Linked List.java +++ b/Easy/Palindrome Linked List.java @@ -3,32 +3,41 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public boolean isPalindrome(ListNode head) { - ArrayList arr = new ArrayList(); - while (head != null) { - arr.add(head.val); - head = head.next; + ListNode slow = head; + ListNode fast = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; } - - if (arr.size() < 2) return true; - - int i=0; - int j = arr.size()-1; - - while (true) { - - if (arr.get(i).equals(arr.get(j)) == false) return false; - - if (arr.size()%2 == 0 && j - i == 1) break; - if (arr.size()%2 != 0 && j - i == 2) break; - - i++; - j--; + ListNode secondHalf = slow; + secondHalf = reverse(secondHalf); + ListNode firstHalf = head; + while (secondHalf != null && firstHalf != null) { + if (firstHalf.val != secondHalf.val) { + return false; + } + firstHalf = firstHalf.next; + secondHalf = secondHalf.next; } return true; } + + private ListNode reverse(ListNode node) { + ListNode curr = node; + ListNode prev = null; + while (curr != null) { + ListNode next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + return prev; + } } diff --git a/Easy/Palindrome Number.java b/Easy/Palindrome Number.java index 6c5be699..a3206088 100644 --- a/Easy/Palindrome Number.java +++ b/Easy/Palindrome Number.java @@ -3,15 +3,13 @@ public boolean isPalindrome(int x) { if (x < 0) { return false; } - return x - reverse(x) == 0; - } - - private int reverse(int n) { - int newNum = 0; - while (n > 0) { - newNum = newNum * 10 + n % 10; - n /= 10; + int reversedNum = 0; + int xCopy = x; + while (x > 0) { + int rem = x % 10; + reversedNum = reversedNum * 10 + rem; + x /= 10; } - return newNum; + return reversedNum == xCopy; } } diff --git a/Easy/Palindrome Permutation.java b/Easy/Palindrome Permutation.java index f1d5b084..ce4bccb8 100644 --- a/Easy/Palindrome Permutation.java +++ b/Easy/Palindrome Permutation.java @@ -1,13 +1,13 @@ class Solution { public boolean canPermutePalindrome(String s) { - int[] count = new int[256]; + Map frequencyMap = new HashMap<>(); for (char c : s.toCharArray()) { - count[(int) c]++; + frequencyMap.put(c, frequencyMap.getOrDefault(c, 0) + 1); } boolean oddFound = false; - for (int i = 0; i < 256; i++) { - if (count[i] % 2 != 0) { - if (s.length() % 2 == 0 || oddFound) { + for (Character key : frequencyMap.keySet()) { + if (frequencyMap.get(key) % 2 != 0) { + if (oddFound) { return false; } oddFound = true; diff --git a/Easy/Pascal's Triangle II.java b/Easy/Pascal's Triangle II.java index 219b923a..9890275c 100644 --- a/Easy/Pascal's Triangle II.java +++ b/Easy/Pascal's Triangle II.java @@ -1,21 +1,17 @@ class Solution { public List getRow(int rowIndex) { - int count = 0; - List list = new ArrayList<>(); - List prev = new ArrayList<>(); + List lastRow = new ArrayList<>(); for (int i = 0; i <= rowIndex; i++) { - prev = list; - List temp = new ArrayList<>(); + List copy = new ArrayList<>(lastRow); + lastRow.clear(); for (int j = 0; j <= i; j++) { if (j == 0 || j == i) { - temp.add(1); - } - else { - temp.add(prev.get(j - 1) + prev.get(j)); + lastRow.add(1); + } else { + lastRow.add(copy.get(j - 1) + copy.get(j)); } } - list = temp; } - return list; + return lastRow; } } diff --git a/Easy/Pascal's Triangle.java b/Easy/Pascal's Triangle.java index 5b3b7b8b..86ea8bdb 100644 --- a/Easy/Pascal's Triangle.java +++ b/Easy/Pascal's Triangle.java @@ -1,19 +1,17 @@ class Solution { - public List> generate(int numRows) { - List> ans = new ArrayList<>(); - for (int i = 0; i < numRows; i++) { - List list = new ArrayList<>(); - for (int j = 0; j < i + 1; j++) { - if (j == 0 || j == i) { - list.add(1); + public List> generate(int numRows) { + List> result = new ArrayList<>(); + for (int i = 0; i < numRows; i++) { + List temp = new ArrayList<>(); + for (int j = 0; j <= i; j++) { + if (j == 0 || j == i) { + temp.add(1); + } else { + temp.add(result.get(i - 1).get(j - 1) + result.get(i - 1).get(j)); + } + } + result.add(temp); } - else { - list.add(ans.get(i - 1).get(j - 1) + ans.get(i - 1).get(j)); - } - } - System.out.println(list); - ans.add(list); + return result; } - return ans; - } } diff --git a/Easy/Pass the Pillow.java b/Easy/Pass the Pillow.java new file mode 100644 index 00000000..e9ae16ea --- /dev/null +++ b/Easy/Pass the Pillow.java @@ -0,0 +1,7 @@ +class Solution { + public int passThePillow(int n, int time) { + int factor = time / (n - 1); + int remainder = time % (n - 1); + return factor % 2 != 0 ? (n - remainder) : (1 + remainder); + } +} diff --git a/Easy/Path Crossing.java b/Easy/Path Crossing.java index 32b241c3..e3f7d9a9 100644 --- a/Easy/Path Crossing.java +++ b/Easy/Path Crossing.java @@ -1,21 +1,29 @@ class Solution { - int[][] dirs = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}}; - public boolean isPathCrossing(String path) { - Set set = new HashSet<>(); - int currX = 0; - int currY = 0; - String dirSymbol = "NSEW"; - set.add(currX + "|" + currY); - for (char c : path.toCharArray()) { - int dirIdx = dirSymbol.indexOf(c); - currX += dirs[dirIdx][0]; - currY += dirs[dirIdx][1]; - String hash = currX + "|" + currY; - if (set.contains(hash)) { - return true; - } - set.add(hash); + public boolean isPathCrossing(String path) { + Set visited = new HashSet<>(); + visited.add("0|0"); + int x = 0; + int y = 0; + for (Character step : path.toCharArray()) { + switch (step) { + case 'N': + x++; + break; + case 'S': + x--; + break; + case 'E': + y--; + break; + case 'W': + y++; + break; + } + String key = x + "|" + y; + if (!visited.add(key)) { + return true; + } + } + return false; } - return false; - } } diff --git a/Easy/Path Sum III.java b/Easy/Path Sum III.java deleted file mode 100644 index 08c0fd85..00000000 --- a/Easy/Path Sum III.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public int pathSum(TreeNode root, int sum) { - if (root == null) { - return 0; - } - return helper(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum); - } - - private int helper(TreeNode root, int sum) { - if (root == null) { - return 0; - } - return (root.val == sum ? 1 : 0) + helper(root.left, sum - root.val) + helper(root.right, sum - root.val); - } -} diff --git a/Easy/Path Sum.java b/Easy/Path Sum.java index 537ec4bb..dc77aafe 100644 --- a/Easy/Path Sum.java +++ b/Easy/Path Sum.java @@ -4,17 +4,39 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public boolean hasPathSum(TreeNode root, int sum) { - - if (root == null) return false; - if (root.left == null && root.right == null) { - return sum - root.val == 0; - } - - return (root.left != null ? hasPathSum(root.left, sum-root.val) : false) | (root.right != null ? hasPathSum(root.right, sum-root.val) : false); + public boolean hasPathSum(TreeNode root, int targetSum) { + if (root == null) { + return false; } + Queue sumQueue = new LinkedList<>(); + Queue nodeQueue = new LinkedList<>(); + sumQueue.add(targetSum - root.val); + nodeQueue.add(root); + while (!nodeQueue.isEmpty()) { + TreeNode removedNode = nodeQueue.remove(); + int removedSum = sumQueue.remove(); + if (removedNode.left == null && removedNode.right == null && removedSum == 0) { + return true; + } + if (removedNode.left != null) { + nodeQueue.add(removedNode.left); + sumQueue.add(removedSum - removedNode.left.val); + } + if (removedNode.right != null) { + nodeQueue.add(removedNode.right); + sumQueue.add(removedSum - removedNode.right.val); + } + } + return false; + } } diff --git a/Easy/Peak Index in a Mountain Array.java b/Easy/Peak Index in a Mountain Array.java deleted file mode 100644 index 818dbf9c..00000000 --- a/Easy/Peak Index in a Mountain Array.java +++ /dev/null @@ -1,16 +0,0 @@ -class Solution { - public int peakIndexInMountainArray(int[] A) { - int low = 0; - int high = A.length - 1; - while (low < high) { - int mid = low + (high - low) / 2; - if (A[mid] < A[mid + 1]) { - low = mid + 1; - } - else { - high = mid; - } - } - return low; - } -} diff --git a/Easy/Percentage of Letter in String.java b/Easy/Percentage of Letter in String.java new file mode 100644 index 00000000..96c0526c --- /dev/null +++ b/Easy/Percentage of Letter in String.java @@ -0,0 +1,11 @@ +class Solution { + public int percentageLetter(String s, char letter) { + int letterCount = 0; + for (char c : s.toCharArray()) { + if (c == letter) { + letterCount++; + } + } + return (letterCount * 100) / s.length(); + } +} diff --git a/Easy/Perfect Number.java b/Easy/Perfect Number.java index 5afc8d1c..6ce680f2 100644 --- a/Easy/Perfect Number.java +++ b/Easy/Perfect Number.java @@ -1,16 +1,18 @@ class Solution { - public boolean checkPerfectNumber(int num) { - if (num == 1) return false; - int sum = 0; - int i = 2; - while (i <= Math.sqrt(num)) { - if (num%i == 0) { - sum += i + num/i; - } - i++; - } - sum++; - - return sum == num; + public boolean checkPerfectNumber(int num) { + if (num == 1) { + return false; + } + return getDivisorSum(num) == num; + } + + private int getDivisorSum(int num) { + int sum = 0; + for (int i = 2; i <= Math.sqrt(num); i++) { + if (num % i == 0) { + sum += i + num / i; + } } + return sum + 1; + } } diff --git a/Easy/Points That Intersect With Cars.java b/Easy/Points That Intersect With Cars.java new file mode 100644 index 00000000..8443505c --- /dev/null +++ b/Easy/Points That Intersect With Cars.java @@ -0,0 +1,20 @@ +class Solution { + public int numberOfPoints(List> coordinates) { + coordinates.sort(Comparator.comparingInt((List o) -> o.get(0)).thenComparingInt(o -> o.get(1))); + int points = 0; + int intervalStart = -1; + int intervalEnd = -1; + for (List coordinate : coordinates) { + if (intervalStart == -1) { + intervalStart = coordinate.get(0); + } else { + if (intervalEnd < coordinate.get(0)) { + points += intervalEnd - intervalStart + 1; + intervalStart = coordinate.get(0); + } + } + intervalEnd = Math.max(intervalEnd, coordinate.get(1)); + } + return points + intervalEnd - intervalStart + 1; + } +} diff --git a/Easy/Positions of Large Groups.java b/Easy/Positions of Large Groups.java index 0e54382f..7258f529 100644 --- a/Easy/Positions of Large Groups.java +++ b/Easy/Positions of Large Groups.java @@ -1,32 +1,17 @@ class Solution { - public List> largeGroupPositions(String S) { - List> positions = new ArrayList<>(); - - int i = 1; - int count = 1; - int start = 0; - - while (i < S.length()) { - if (S.charAt(i) == S.charAt(i-1)) { - count++; + public List> largeGroupPositions(String s) { + List> result = new ArrayList<>(); + int idx = 0; + while (idx < s.length()) { + int startIdx = idx; + char c = s.charAt(idx); + while (idx < s.length() && s.charAt(idx) == c) { + idx++; } - else { - if (count >= 3) { - List temp = Arrays.asList(start, i-1); - positions.add(temp); - } - - start = i; - count = 1; + if (idx - startIdx >= 3) { + result.add(Arrays.asList(startIdx, idx - 1)); } - - i++; } - - if (count >= 3) { - positions.add(Arrays.asList(start, i-1)); - } - - return positions; + return result; } } diff --git a/Easy/Power of Four.java b/Easy/Power of Four.java new file mode 100644 index 00000000..269c7bd7 --- /dev/null +++ b/Easy/Power of Four.java @@ -0,0 +1,5 @@ +class Solution { + public boolean isPowerOfFour(int n) { + return n > 0 && Math.log(n) / Math.log(2) % 2 == 0; + } +} diff --git a/Easy/Power of Three.java b/Easy/Power of Three.java new file mode 100644 index 00000000..2fbe03e5 --- /dev/null +++ b/Easy/Power of Three.java @@ -0,0 +1,19 @@ +class Solution { + public boolean isPowerOfThree(int n) { + int left = 0; + int right = n / 3; + while (left <= right) { + int mid = (left + right) / 2; + double powValue = Math.pow(3, mid); + if (powValue == n) { + return true; + } + if (powValue > n) { + right = mid - 1; + } else { + left = mid + 1; + } + } + return false; + } +} diff --git a/Easy/Power of Two.java b/Easy/Power of Two.java index c4ddd0f3..caf0d77a 100644 --- a/Easy/Power of Two.java +++ b/Easy/Power of Two.java @@ -1,21 +1,19 @@ class Solution { public boolean isPowerOfTwo(int n) { - if (n % 2 != 0 && n != 1) { + if (n > 1 && n % 2 != 0) { return false; } int start = 0; int end = n / 2; while (start <= end) { int mid = (start + end) / 2; - int pow = (int) (Math.pow(2, mid)); - if (n == pow) { + int pow = (int) Math.pow(2, mid); + if (pow == n) { return true; - } - else if (n > pow) { - start = mid + 1; - } - else { + } else if (pow > n) { end = mid - 1; + } else { + start = mid + 1; } } return false; diff --git a/Easy/Power of four.java b/Easy/Power of four.java deleted file mode 100644 index 254d5097..00000000 --- a/Easy/Power of four.java +++ /dev/null @@ -1,20 +0,0 @@ -class Solution { - public boolean isPowerOfFour(int num) { - long start = 0; - long end = num / 4; - while (start <= end) { - long mid = (start + end) / 2; - long pow = (long) Math.pow(4, mid); - if (pow == (long) num) { - return true; - } - else if (pow > (long) num) { - end = mid - 1; - } - else { - start = mid + 1; - } - } - return false; - } -} diff --git a/Easy/Power of three.java b/Easy/Power of three.java deleted file mode 100644 index 4e99c550..00000000 --- a/Easy/Power of three.java +++ /dev/null @@ -1,5 +0,0 @@ -class Solution { - public boolean isPowerOfThree(int n) { - return n>0 && 1162261467%n==0; - } -} diff --git a/Easy/Prime In Diagonal.java b/Easy/Prime In Diagonal.java new file mode 100644 index 00000000..16b34fda --- /dev/null +++ b/Easy/Prime In Diagonal.java @@ -0,0 +1,30 @@ +class Solution { + public int diagonalPrime(int[][] nums) { + int n = nums.length; + int maxPrime = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if ((i == j || i + j == n - 1) && isPrime(nums[i][j])) { + maxPrime = Math.max(maxPrime, nums[i][j]); + } + } + } + return maxPrime; + } + + private static boolean isPrime(int n) { + if (n <= 1) { + return false; + } + if (n == 2) { + return true; + } + int midPoint = ((int) Math.sqrt(n)) + 1; + for (int i = 2; i <= midPoint; i++) { + if (n % i == 0) { + return false; + } + } + return true; + } +} diff --git a/Easy/README.md b/Easy/README.md index b9713c84..ff578ea7 100644 --- a/Easy/README.md +++ b/Easy/README.md @@ -1,284 +1,609 @@ # Easy LeetCode-Java-Solutions S.no | Coding Problem --- | --- -1|[Pascal's Triangle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Pascal's%20Triangle.java) -2|[Meeting Rooms](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Meeting%20Rooms.java) -3|[Reverse Bits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20Bits.java) -4|[Cousins in Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Cousins%20in%20Binary%20Tree.java) -5|[Keyboard Row](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Keyboard%20Row.java) -6|[Largest Unique Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Largest%20Unique%20Number.java) -7|[Assign Cookies](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Assign%20Cookies.java) -8|[Maximum Depth of N-ary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Depth%20of%20N-ary%20Tree.java) -9|[Count and Say](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20and%20Say.java) -10|[Arranging Coins](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Arranging%20Coins.java) -11|[Maximum Number of Balloons](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Number%20of%20Balloons.java) -12|[Construct the rectangle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Construct%20the%20rectangle.java) -13|[Magic Squares In Grid](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Magic%20Squares%20In%20Grid.java) -14|[Matrix Cells in Distance Order](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Matrix%20Cells%20in%20Distance%20Order.java) -15|[1-bit and 2-bit Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/1-bit%20and%202-bit%20Characters.java) -16|[Find the difference](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20difference.java) -17|[Factorial Trailing Zeroes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Factorial%20Trailing%20Zeroes.java) -18|[Sentence Similarity](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sentence%20Similarity.java) -19|[Largest Number At Least Twice of Others](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Largest%20Number%20At%20Least%20Twice%20of%20Others.java) -20|[Max Area of Island](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Max%20Area%20of%20Island.java) -21|[Longest Palindrome](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Palindrome.java) -22|[Shortest Word Distance III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Shortest%20Word%20Distance%20III.java) -23|[String Compression](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/String%20Compression.java) -24|[trailing_zeroes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/trailing_zeroes.java) -25|[Greatest Common Divisor of Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Greatest%20Common%20Divisor%20of%20Strings.java) -26|[Two Sum IV - Input is a BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Two%20Sum%20IV%20-%20Input%20is%20a%20BST.java) -27|[Linked List Cycle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Linked%20List%20Cycle.java) -28|[Delete node in a linked list](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Delete%20node%20in%20a%20linked%20list.java) -29|[Excel Sheet Column Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Excel%20Sheet%20Column%20Number.java) -30|[Pairs of Songs With Total Durations Divisible by 60](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Pairs%20of%20Songs%20With%20Total%20Durations%20Divisible%20by%2060.java) -31|[Remove Linked List Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20Linked%20List%20Elements.java) -32|[Single-Row Keyboard](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Single-Row%20Keyboard.java) -33|[Missing Number In Arithmetic Progression](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Missing%20Number%20In%20Arithmetic%20Progression.java) -34|[Sum of left leaves](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20of%20left%20leaves.java) -35|[Design Compressed String Iterator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Design%20Compressed%20String%20Iterator.java) -36|[Valid Boomerang](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Boomerang.java) -37|[Flip Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Flip%20Game.java) -38|[Available Captures for Rook](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Available%20Captures%20for%20Rook.java) -39|[Strobogrammatic Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Strobogrammatic%20Number.java) -40|[Add to Array-Form of Integer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Add%20to%20Array-Form%20of%20Integer.java) -41|[Reverse words in a String III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20words%20in%20a%20String%20III.java) -42|[Lowest Common Ancestor of a Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Lowest%20Common%20Ancestor%20of%20a%20Binary%20Search%20Tree.java) -43|[Find Mode in Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Mode%20in%20Binary%20Search%20Tree.java) -44|[Number of 1 bits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%201%20bits.java) -45|[Increasing Order Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Increasing%20Order%20Search%20Tree.java) -46|[Occurrences After Bigram](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Occurrences%20After%20Bigram.java) -47|[Design HashSet](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Design%20HashSet.java) -48|[Excel Sheet Column Title](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Excel%20Sheet%20Column%20Title.java) -49|[Find All Numbers Disappeared in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20All%20Numbers%20Disappeared%20in%20an%20Array.java) -50|[sum_of_two_integers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/sum_of_two_integers.java) -51|[Logger Rate Limiter](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Logger%20Rate%20Limiter.java) -52|[Path Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Path%20Sum.java) -53|[Search Insert Position](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Search%20Insert%20Position.java) -54|[Search in a Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Search%20in%20a%20Binary%20Search%20Tree.java) -55|[Number of Equivalent Domino Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Equivalent%20Domino%20Pairs.java) -56|[Jewels and Stones](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Jewels%20and%20Stones.java) -57|[Unique Email Addresses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Unique%20Email%20Addresses.java) -58|[Roman to Integer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Roman%20to%20Integer.java) -59|[Count Primes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Primes.java) -60|[Complement of Base 10 Integer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Complement%20of%20Base%2010%20Integer.java) -61|[Maximum Subarray](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Subarray.java) -62|[contains_duplicates](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/contains_duplicates.java) -63|[Number of Boomerangs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Boomerangs.java) -64|[Valid Parantheses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Parantheses.java) -65|[remove_duplicates_sorted](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/remove_duplicates_sorted.java) -66|[Sum of square numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20of%20square%20numbers.java) -67|[add_digit](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/add_digit.java) -68|[Letter Case Permutation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Letter%20Case%20Permutation.java) -69|[Transpose Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Transpose%20Matrix.java) -70|[Binary Number with Alternating Bits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Number%20with%20Alternating%20Bits.java) -71|[Power of three](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Power%20of%20three.java) -72|[Remove All Adjacent Duplicates In String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20All%20Adjacent%20Duplicates%20In%20String.java) -73|[Longest Continuous Increasing Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Continuous%20Increasing%20Subsequence.java) -74|[Palindrome Permutation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Palindrome%20Permutation.java) -75|[Valid Word Sequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Word%20Sequence.java) -76|[Powerful Integers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Powerful%20Integers.java) -77|[Isomorphic Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Isomorphic%20Strings.java) -78|[Uncommon Words from Two Sentences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Uncommon%20Words%20from%20Two%20Sentences.java) -79|[Design HashMap](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Design%20HashMap.java) -80|[Backspace String Compare](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Backspace%20String%20Compare.java) -81|[Max Consecutive Ones](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Max%20Consecutive%20Ones.java) -82|[Happy Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Happy%20Number.java) -83|[Path Sum III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Path%20Sum%20III.java) -84|[Shortest Word Distance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Shortest%20Word%20Distance.java) -85|[Binary Prefix Divisible By 5](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Prefix%20Divisible%20By%205.java) -86|[Leaf-Similar Trees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Leaf-Similar%20Trees.java) -87|[Nested List Weight Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Nested%20List%20Weight%20Sum.java) -88|[Guess Number Higher or Lower](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Guess%20Number%20Higher%20or%20Lower.java) -89|[Monotonic Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Monotonic%20Array.java) -90|[ugly_number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/ugly_number.java) -91|[Number of Days in a Month](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Days%20in%20a%20Month.java) -92|[Two Sum III - Data Structure Design](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Two%20Sum%20III%20-%20Data%20Structure%20Design.java) -93|[Island Perimeter](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Island%20Perimeter.java) -94|[SqrtX](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/SqrtX.java) -95|[Fair Candy Swap](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Fair%20Candy%20Swap.java) -96|[Heaters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Heaters.java) -97|[Trim a Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Trim%20a%20Binary%20Search%20Tree.java) -98|[First Bad Version](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/First%20Bad%20Version.java) -99|[Single Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Single%20Number.java) -100|[Closest Binary Search Tree Value](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Closest%20Binary%20Search%20Tree%20Value.java) -101|[Shortest Word Distance II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Shortest%20Word%20Distance%20II.java) -102|[Symmetric Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Symmetric%20Tree.java) -103|[Minimum Absolute Difference](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Absolute%20Difference.java) -104|[Valid Palindrome II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Palindrome%20II.java) -105|[Read N characters Given Read4](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Read%20N%20characters%20Given%20Read4.java) -106|[N-ary Tree Level Order Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/N-ary%20Tree%20Level%20Order%20Traversal.java) -107|[Reverse String II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20String%20II.java) -108|[Degree of an array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Degree%20of%20an%20array.java) -109|[Find All Anagrams in a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20All%20Anagrams%20in%20a%20String.java) -110|[Submission Detail](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Submission%20Detail.java) -111|[Binary Tree Paths](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Tree%20Paths.java) -112|[Rotate Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Rotate%20Array.java) -113|[Day of the Year](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Day%20of%20the%20Year.java) -114|[Set Mismatch](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Set%20Mismatch.java) -115|[majority_element](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/majority_element.java) -116|[Number Complement](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20Complement.java) -117|[power_of_2](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/power_of_2.java) -118|[Can Place Flowers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Can%20Place%20Flowers.java) -119|[Largest Perimeter Triangle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Largest%20Perimeter%20Triangle.java) -120|[Relative ranks](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Relative%20ranks.java) -121|[Convert BST to greater tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Convert%20BST%20to%20greater%20tree.java) -122|[valid_anagrams](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/valid_anagrams.java) -123|[License Key Formatting](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/License%20Key%20Formatting.java) -124|[Verifying an Alien Dictionary](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Verifying%20an%20Alien%20Dictionary.java) -125|[Diameter of Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Diameter%20of%20Binary%20Tree.java) -126|[first_unique_character_in_a_string](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/first_unique_character_in_a_string.java) -127|[Moving Average from Data Stream](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Moving%20Average%20from%20Data%20Stream.java) -128|[Diet Plan Performance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Diet%20Plan%20Performance.java) -129|[Subdomain Visit Count](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Subdomain%20Visit%20Count.java) -130|[Duplicate Zeros](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Duplicate%20Zeros.java) -131|[Same Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Same%20Tree.java) -132|[FizzBuzz](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/FizzBuzz.java) -133|[Buddy Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Buddy%20Strings.java) -134|[Third Maximum Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Third%20Maximum%20Number.java) -135|[Pascal's Triangle II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Pascal's%20Triangle%20II.java) -136|[Word Pattern](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Word%20Pattern.java) -137|[Hamming Distance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Hamming%20Distance.java) -138|[Minimum Distance Between BST Nodes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Distance%20Between%20BST%20Nodes.java) -139|[Find Words That Can Be Formed by Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Words%20That%20Can%20Be%20Formed%20by%20Characters.java) -140|[Defanging an IP Address](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Defanging%20an%20IP%20Address.java) -141|[Reverse Vowels of a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20Vowels%20of%20a%20String.java) -142|[Balanced Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Balanced%20Binary%20Tree.java) -143|[How Many Apples Can You Put into the Basket](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/How%20Many%20Apples%20Can%20You%20Put%20into%20the%20Basket.java) -144|[String Without AAA or BBB](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/String%20Without%20AAA%20or%20BBB.java) -145|[Implement Queue using Stacks](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Implement%20Queue%20using%20Stacks.java) -146|[Baseball Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Baseball%20Game.java) -147|[range_addition_II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/range_addition_II.java) -148|[Design Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Design%20Linked%20List.java) -149|[Convert a number to hexadecimal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Convert%20a%20number%20to%20hexadecimal.java) -150|[Toeplitz Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Toeplitz%20Matrix.java) -151|[N-th Tribonacci Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/N-th%20Tribonacci%20Number.java) -152|[Kth Largest Element in a Stream](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Kth%20Largest%20Element%20in%20a%20Stream.java) -153|[N-ary Tree Preorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/N-ary%20Tree%20Preorder%20Traversal.java) -154|[Paint House](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Paint%20House.java) -155|[Peak Index in a Mountain Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Peak%20Index%20in%20a%20Mountain%20Array.java) -156|[Binary Search](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Search.java) -157|[Two Sum Less Than K](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Two%20Sum%20Less%20Than%20K.java) -158|[Maximum depth of Binary tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20depth%20of%20Binary%20tree.java) -159|[Rotting Oranges](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Rotting%20Oranges.java) -160|[Armstrong Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Armstrong%20Number.java) -161|[Best time to buy & sell a stock II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Best%20time%20to%20buy%20&%20sell%20a%20stock%20II.java) -162|[Base 7](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Base%207.java) -163|[Longest Univalue Path](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Univalue%20Path.java) -164|[Repeated Substring Pattern](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Repeated%20Substring%20Pattern.java) -165|[Maximum Distance in Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Distance%20in%20Arrays.java) -166|[Relative Sort Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Relative%20Sort%20Array.java) -167|[Unique Number of Occurrences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Unique%20Number%20of%20Occurrences.java) -168|[Last Stone Weight](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Last%20Stone%20Weight.java) -169|[Largest Triangle Area](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Largest%20Triangle%20Area.java) -170|[Min Cost Climbing Stairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Min%20Cost%20Climbing%20Stairs.java) -171|[Number of Lines To Write String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Lines%20To%20Write%20String.java) -172|[Detect Capital](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Detect%20Capital.java) -173|[Two Sum II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Two%20Sum%20II.java) -174|[Distance Between Bus Stops](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Distance%20Between%20Bus%20Stops.java) -175|[Sum of Digits in the Minimum Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20of%20Digits%20in%20the%20Minimum%20Number.java) -176|[Check If a Number Is Majority Element in a Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20If%20a%20Number%20Is%20Majority%20Element%20in%20a%20Sorted%20Array.java) -177|[Merge two binary trees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Merge%20two%20binary%20trees.java) -178|[Construct String from Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Construct%20String%20from%20Binary%20Tree.java) -179|[Merge Sorted Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Merge%20Sorted%20Arrays.java) -180|[N-Repeated Element in Size 2N Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/N-Repeated%20Element%20in%20Size%202N%20Array.java) -181|[Intersection of two arrays II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Intersection%20of%20two%20arrays%20II.java) -182|[Two City Scheduling](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Two%20City%20Scheduling.java) -183|[High Five](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/High%20Five.java) -184|[Contains Duplicate II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Contains%20Duplicate%20II.java) -185|[Intersection of two Linked Lists](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Intersection%20of%20two%20Linked%20Lists.java) -186|[Confusing Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Confusing%20Number.java) -187|[Fixed Point](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Fixed%20Point.java) -188|[To Lower Case](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/To%20Lower%20Case.java) -189|[Flipping an Image](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Flipping%20an%20Image.java) -190|[Count Binary Substrings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Binary%20Substrings.java) -191|[Maximum Subarray Sum I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Subarray%20Sum%20I.java) -192|[Reshape the matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reshape%20the%20matrix.java) -193|[Shortest Distance to a Character](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Shortest%20Distance%20to%20a%20Character.java) -194|[Find Pivot Index](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Pivot%20Index.java) -195|[Add Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Add%20Strings.java) -196|[Reverse Integer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20Integer.java) -197|[Find the Town Judge](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20Town%20Judge.java) -198|[Rotated Digits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Rotated%20Digits.java) -199|[Merge Two Sorted Lists](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Merge%20Two%20Sorted%20Lists.java) -200|[Reverse Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20Linked%20List.java) -201|[Repeated String Match](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Repeated%20String%20Match.java) -202|[Subtree of Another Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Subtree%20of%20Another%20Tree.java) -203|[Groups of Special-Equivalent Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Groups%20of%20Special-Equivalent%20Strings.java) -204|[Maximum Product of three numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Product%20of%20three%20numbers.java) -205|[Implement Stack using Queues](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Implement%20Stack%20using%20Queues.java) -206|[Height Checker](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Height%20Checker.java) -207|[Two Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Two%20Sum.java) -208|[Compare Strings by Frequency of the Smallest Character](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Compare%20Strings%20by%20Frequency%20of%20the%20Smallest%20Character.java) -209|[Most Common Word](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Most%20Common%20Word.java) -210|[Binary Tree Level Order Traversal II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Tree%20Level%20Order%20Traversal%20II.java) -211|[Longest Word in Dictionary](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Word%20in%20Dictionary.java) -212|[Min Stack](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Min%20Stack.java) -213|[Image Smoother](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Image%20Smoother.java) -214|[Shortest Unsorted Continuous Subarray](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Shortest%20Unsorted%20Continuous%20Subarray.java) -215|[Missing Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Missing%20Numbers.java) -216|[Remove Duplicates From Sorted Lists](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20Duplicates%20From%20Sorted%20Lists.java) -217|[Path In Zigzag Labelled Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Path%20In%20Zigzag%20Labelled%20Binary%20Tree.java) -218|[Max Stack](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Max%20Stack.java) -219|[Minimum Depth of a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Depth%20of%20a%20Binary%20Tree.java) -220|[Split a String in Balanced Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Split%20a%20String%20in%20Balanced%20Strings.java) -221|[Length of last word](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Length%20of%20last%20word.java) -222|[Second Minimum Node in a binary tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Second%20Minimum%20Node%20in%20a%20binary%20tree.java) -223|[Average of levels in a binary tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Average%20of%20levels%20in%20a%20binary%20tree.java) -224|[Employee Importance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Employee%20Importance.java) -225|[Minimum Absolute Difference in BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20%20Absolute%20Difference%20in%20BST.java) -226|[Flood Fill](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Flood%20Fill.java) -227|[Distribute Candies to People](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Distribute%20Candies%20to%20People.java) -228|[Ransom Note](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Ransom%20Note.java) -229|[Valid Word Abbrevation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Word%20Abbrevation.java) -230|[Student Attendance Record I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Student%20Attendance%20Record%20I.java) -231|[Minimum Moves to Equal an Array Element](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Moves%20to%20Equal%20an%20Array%20Element.java) -232|[Bold Words in String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Bold%20Words%20in%20String.java) -233|[nim_game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/nim_game.java) -234|[Next Greater Element](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Next%20Greater%20Element.java) -235|[Non-decreasing Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Non-decreasing%20Array.java) -236|[remove_element](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/remove_element.java) -237|[Projection Area of 3D Shapes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Projection%20Area%20of%203D%20Shapes.java) -238|[Palindrome Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Palindrome%20Number.java) -239|[Sum of Even Numbers After Queries](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20of%20Even%20Numbers%20After%20Queries.java) -240|[Squares of a Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Squares%20of%20a%20Sorted%20Array.java) -241|[Judge Route Cycle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Judge%20Route%20Cycle.java) -242|[intersection_of_two_arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/intersection_of_two_arrays.java) -243|[move_zeroes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/move_zeroes.java) -244|[Rotate String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Rotate%20String.java) -245|[Binary Gap](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Gap.java) -246|[Perfect Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Perfect%20Number.java) -247|[House Robber](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/House%20Robber.java) -248|[Maximize Distance to Closest Person](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximize%20Distance%20to%20Closest%20Person.java) -249|[Power of four](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Power%20of%20four.java) -250|[Longest Uncommon Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Uncommon%20Subsequence.java) -251|[Unique Morse Code Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Unique%20Morse%20Code%20Words.java) -252|[Univalued Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Univalued%20Binary%20Tree.java) -253|[Plus One](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Plus%20One.java) -254|[Add Binary](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Add%20Binary.java) -255|[Reverse String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20String.java) -256|[Middle of the linked list](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Middle%20of%20the%20linked%20list.java) -257|[K Closest Points to Origin](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/K%20Closest%20Points%20to%20Origin.java) -258|[Distribute Candies](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Distribute%20Candies.java) -259|[Positions of Large Groups](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Positions%20of%20Large%20Groups.java) -260|[N-ary Tree Postorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/N-ary%20Tree%20Postorder%20Traversal.java) -261|[Fibonacci Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Fibonacci%20Numbers.java) -262|[Remove Vowels from a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20Vowels%20from%20a%20String.java) -263|[Goat Latin](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Goat%20Latin.java) -264|[Climbing Stairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Climbing%20Stairs.java) -265|[Best time to buy & sell a stock](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Best%20time%20to%20buy%20&%20sell%20a%20stock.java) -266|[Invert a binary tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Invert%20a%20binary%20tree.java) -267|[Longest Harmonious Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Harmonious%20Subsequence.java) -268|[Palindrome Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Palindrome%20Linked%20List.java) -269|[Implement strStr](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Implement%20strStr.java) -270|[K-diff Pairs in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/K-diff%20Pairs%20in%20an%20Array.java) -271|[Range Sum Query_Immutable](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Range%20Sum%20Query_Immutable.java) -272|[Convert Sorted Array To Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Convert%20Sorted%20Array%20To%20Binary%20Search%20Tree.java) -273|[Number of segments in a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20segments%20in%20a%20String.java) -274|[Count Substrings with Only One Distinct Letter](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Substrings%20with%20Only%20One%20Distinct%20Letter.java) -275|[Valid Palindrome](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Palindrome.java) -276|[Binary Tree Tilt](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Tree%20Tilt.java) -277|[Valid Perfect Square](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Perfect%20Square.java) -278|[Minimum_index_sum_of_two_lists](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum_index_sum_of_two_lists.java) -279|[Paint Fence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Paint%20Fence.java) -280|[Longest Common Prefix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Common%20Prefix.java) -281|[Array Partition I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Array%20Partition%20I.java) +1|[Count Binary Substrings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Binary%20Substrings.java) +2|[Check if All A's Appears Before All B's](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20All%20A's%20Appears%20Before%20All%20B's.java) +3|[Longest Harmonious Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Harmonious%20Subsequence.java) +4|[Missing Ranges](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Missing%20Ranges.java) +5|[High Five](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/High%20Five.java) +6|[Binary Tree Tilt](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Tree%20Tilt.java) +7|[Number of Boomerangs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Boomerangs.java) +8|[Count the Number of Consistent Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20the%20Number%20of%20Consistent%20Strings.java) +9|[Sentence Similarity](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sentence%20Similarity.java) +10|[Strong Password Checker II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Strong%20Password%20Checker%20II.java) +11|[Perform String Shifts](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Perform%20String%20Shifts.java) +12|[Kth Largest Element in a Stream](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Kth%20Largest%20Element%20in%20a%20Stream.java) +13|[Kth Missing Positive Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Kth%20Missing%20Positive%20Number.java) +14|[Check If String Is a Prefix of Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20If%20String%20Is%20a%20Prefix%20of%20Array.java) +15|[Capitalize the Title](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Capitalize%20the%20Title.java) +16|[The K Weakest Rows in a Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/The%20K%20Weakest%20Rows%20in%20a%20Matrix.java) +17|[Missing Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Missing%20Number.java) +18|[Remove Duplicates from Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20Duplicates%20from%20Sorted%20Array.java) +19|[Implement strStr](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Implement%20strStr.java) +20|[Reverse String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20String.java) +21|[Create Target Array in the Given Order](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Create%20Target%20Array%20in%20the%20Given%20Order.java) +22|[Increasing Order Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Increasing%20Order%20Search%20Tree.java) +23|[Minimum Number of Moves to Seat Everyone](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Number%20of%20Moves%20to%20Seat%20Everyone.java) +24|[Minimum Absolute Difference](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Absolute%20Difference.java) +25|[Maximum 69 Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%2069%20Number.java) +26|[Largest Perimeter Triangle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Largest%20Perimeter%20Triangle.java) +27|[Minimum Cost of Buying Candies With Discount](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Cost%20of%20Buying%20Candies%20With%20Discount.java) +28|[Number of Equivalent Domino Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Equivalent%20Domino%20Pairs.java) +29|[Summary Ranges](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Summary%20Ranges.java) +30|[Binary Number with Alternating Bits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Number%20with%20Alternating%20Bits.java) +31|[Find the Distinct Difference Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20Distinct%20Difference%20Array.java) +32|[Buy Two Chocolates](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Buy%20Two%20Chocolates.java) +33|[Intersection of Multiple Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Intersection%20of%20Multiple%20Arrays.java) +34|[Palindrome Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Palindrome%20Linked%20List.java) +35|[Rectangle Overlap](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Rectangle%20Overlap.java) +36|[Intersection of Three Sorted Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Intersection%20of%20Three%20Sorted%20Arrays.java) +37|[Minimum Changes To Make Alternating Binary String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Changes%20To%20Make%20Alternating%20Binary%20String.java) +38|[Jewels and Stones](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Jewels%20and%20Stones.java) +39|[Number of Valid Words in a Sentence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Valid%20Words%20in%20a%20Sentence.java) +40|[Greatest English Letter in Upper and Lower Case](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Greatest%20English%20Letter%20in%20Upper%20and%20Lower%20Case.java) +41|[Unique Email Addresses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Unique%20Email%20Addresses.java) +42|[X of a Kind in a Deck of Cards](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/X%20of%20a%20Kind%20in%20a%20Deck%20of%20Cards.java) +43|[Longest Nice Substring](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Nice%20Substring.java) +44|[Count Primes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Primes.java) +45|[Positions of Large Groups](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Positions%20of%20Large%20Groups.java) +46|[Maximum Population Year](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Population%20Year.java) +47|[Min Cost Climbing Stairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Min%20Cost%20Climbing%20Stairs.java) +48|[Number of Days Between Two Dates](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Days%20Between%20Two%20Dates.java) +49|[Minimum Distance to the Target Element](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Distance%20to%20the%20Target%20Element.java) +50|[Path Crossing](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Path%20Crossing.java) +51|[Check If N and Its Double Exist](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20If%20N%20and%20Its%20Double%20Exist.java) +52|[Word Pattern](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Word%20Pattern.java) +53|[Maximum Nesting Depth of the Parentheses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Nesting%20Depth%20of%20the%20Parentheses.java) +54|[Two Sum IV - Input is a BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Two%20Sum%20IV%20-%20Input%20is%20a%20BST.java) +55|[Find Positive Integer Solution for a Given Equation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Positive%20Integer%20Solution%20for%20a%20Given%20Equation.java) +56|[Hamming Distance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Hamming%20Distance.java) +57|[Defuse the Bomb](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Defuse%20the%20Bomb.java) +58|[Check if The Number is Fascinating](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20The%20Number%20is%20Fascinating.java) +59|[Minimum Common Value](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Common%20Value.java) +60|[Final Prices With a Special Discount in a Shop](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Final%20Prices%20With%20a%20Special%20Discount%20in%20a%20Shop.java) +61|[Plus One](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Plus%20One.java) +62|[Submission Detail](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Submission%20Detail.java) +63|[Rotate String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Rotate%20String.java) +64|[Minimum Depth of a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Depth%20of%20a%20Binary%20Tree.java) +65|[Power of Four](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Power%20of%20Four.java) +66|[Valid Perfect Square](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Perfect%20Square.java) +67|[Find N Unique Integers Sum up to Zero](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20N%20Unique%20Integers%20Sum%20up%20to%20Zero.java) +68|[Remove Trailing Zeros From a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20Trailing%20Zeros%20From%20a%20String.java) +69|[Paint Fence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Paint%20Fence.java) +70|[Detect Capital](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Detect%20Capital.java) +71|[XOR Operation in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/XOR%20Operation%20in%20an%20Array.java) +72|[Divide a String Into Groups of Size k](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Divide%20a%20String%20Into%20Groups%20of%20Size%20k.java) +73|[Flipping an Image](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Flipping%20an%20Image.java) +74|[Subtract the Product and Sum of Digits of an Integer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Subtract%20the%20Product%20and%20Sum%20of%20Digits%20of%20an%20Integer.java) +75|[Two Sum III - Data Structure Design](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Two%20Sum%20III%20-%20Data%20Structure%20Design.java) +76|[Check if Binary String Has at Most One Segment of Ones](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20Binary%20String%20Has%20at%20Most%20One%20Segment%20of%20Ones.java) +77|[Number Complement](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20Complement.java) +78|[Longer Contiguous Segments of Ones than Zeros](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longer%20Contiguous%20Segments%20of%20Ones%20than%20Zeros.java) +79|[Design HashSet](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Design%20HashSet.java) +80|[Convert 1D Array Into 2D Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Convert%201D%20Array%20Into%202D%20Array.java) +81|[Odd String Difference](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Odd%20String%20Difference.java) +82|[Remove Digit From Number to Maximize Result](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20Digit%20From%20Number%20to%20Maximize%20Result.java) +83|[Find Mode in Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Mode%20in%20Binary%20Search%20Tree.java) +84|[Count Hills and Valleys in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Hills%20and%20Valleys%20in%20an%20Array.java) +85|[Maximum Repeating Substring](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Repeating%20Substring.java) +86|[Number of Unequal Triplets in Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Unequal%20Triplets%20in%20Array.java) +87|[Split Strings by Separator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Split%20Strings%20by%20Separator.java) +88|[Find Closest Number to Zero](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Closest%20Number%20to%20Zero.java) +89|[1-bit and 2-bit Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/1-bit%20and%202-bit%20Characters.java) +90|[Binary Gap](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Gap.java) +91|[Subtree of Another Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Subtree%20of%20Another%20Tree.java) +92|[Binary Tree Level Order Traversal II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Tree%20Level%20Order%20Traversal%20II.java) +93|[Count Prefixes of a Given String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Prefixes%20of%20a%20Given%20String.java) +94|[Find the Width of Columns of a Grid](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20Width%20of%20Columns%20of%20a%20Grid.java) +95|[Defanging an IP Address](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Defanging%20an%20IP%20Address.java) +96|[Find Target Indices After Sorting Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Target%20Indices%20After%20Sorting%20Array.java) +97|[Truncate Sentence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Truncate%20Sentence.java) +98|[Diameter of Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Diameter%20of%20Binary%20Tree.java) +99|[Best Poker Hand](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Best%20Poker%20Hand.java) +100|[Range Sum of BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Range%20Sum%20of%20BST.java) +101|[Maximum Average Subarray I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Average%20Subarray%20I.java) +102|[Fizz Buzz](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Fizz%20Buzz.java) +103|[Check if All the Integers in a Range Are Covered](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20All%20the%20Integers%20in%20a%20Range%20Are%20Covered.java) +104|[Find First Palindromic String in the Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20First%20Palindromic%20String%20in%20the%20Array.java) +105|[Duplicate Zeros](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Duplicate%20Zeros.java) +106|[Minimum Subsequence in Non-Increasing Order](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Subsequence%20in%20Non-Increasing%20Order.java) +107|[Smallest Range I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Smallest%20Range%20I.java) +108|[Employee Importance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Employee%20Importance.java) +109|[Minimum_index_sum_of_two_lists](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum_index_sum_of_two_lists.java) +110|[Points That Intersect With Cars](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Points%20That%20Intersect%20With%20Cars.java) +111|[Number of segments in a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20segments%20in%20a%20String.java) +112|[Delete Columns to Make Sorted](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Delete%20Columns%20to%20Make%20Sorted.java) +113|[Reverse Only Letters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20Only%20Letters.java) +114|[Evaluate Boolean Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Evaluate%20Boolean%20Binary%20Tree.java) +115|[Repeated String Match](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Repeated%20String%20Match.java) +116|[Neither Minimum nor Maximum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Neither%20Minimum%20nor%20Maximum.java) +117|[Maximum Value of an Ordered Triplet I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Value%20of%20an%20Ordered%20Triplet%20I.java) +118|[Uncommon Words from Two Sentences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Uncommon%20Words%20from%20Two%20Sentences.java) +119|[Assign Cookies](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Assign%20Cookies.java) +120|[Most Frequent Number Following Key In an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Most%20Frequent%20Number%20Following%20Key%20In%20an%20Array.java) +121|[Element Appearing More Than 25% In Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Element%20Appearing%20More%20Than%2025%%20In%20Sorted%20Array.java) +122|[Find the Town Judge](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20Town%20Judge.java) +123|[Buddy Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Buddy%20Strings.java) +124|[Teoplitz Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Teoplitz%20Matrix.java) +125|[Leaf-Similar Trees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Leaf-Similar%20Trees.java) +126|[Minimum Hours of Training to Win a Competition](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Hours%20of%20Training%20to%20Win%20a%20Competition.java) +127|[Goat Latin](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Goat%20Latin.java) +128|[Flower Planting With No Adjacent](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Flower%20Planting%20With%20No%20Adjacent.java) +129|[Largest Triangle Area](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Largest%20Triangle%20Area.java) +130|[Row With Maximum Ones](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Row%20With%20Maximum%20Ones.java) +131|[Determine Color of a Chessboard Square](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Determine%20Color%20of%20a%20Chessboard%20Square.java) +132|[Richest Customer Wealth](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Richest%20Customer%20Wealth.java) +133|[Consecutive Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Consecutive%20Characters.java) +134|[Latest Time by Replacing Hidden Digits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Latest%20Time%20by%20Replacing%20Hidden%20Digits.java) +135|[Robot Return to Origin](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Robot%20Return%20to%20Origin.java) +136|[Determine Whether Matrix Can Be Obtained By Rotation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Determine%20Whether%20Matrix%20Can%20Be%20Obtained%20By%20Rotation.java) +137|[Flip Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Flip%20Game.java) +138|[Minimum Value to Get Positive Step by Step Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Value%20to%20Get%20Positive%20Step%20by%20Step%20Sum.java) +139|[Average Value of Even Numbers That Are Divisible by Three](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Average%20Value%20of%20Even%20Numbers%20That%20Are%20Divisible%20by%20Three.java) +140|[Reshape the matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reshape%20the%20matrix.java) +141|[Valid Anagram](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Anagram.java) +142|[Number of Strings That Appear as Substrings in Word](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Strings%20That%20Appear%20as%20Substrings%20in%20Word.java) +143|[DI String Match](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/DI%20String%20Match.java) +144|[Running Sum of 1d Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Running%20Sum%20of%201d%20Array.java) +145|[Special Array With X Elements Greater Than or Equal X](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Special%20Array%20With%20X%20Elements%20Greater%20Than%20or%20Equal%20X.java) +146|[Number of Distinct Averages](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Distinct%20Averages.java) +147|[Check if an Array Is Consecutive](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20an%20Array%20Is%20Consecutive.java) +148|[Backspace String Compare](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Backspace%20String%20Compare.java) +149|[Rings and Rods](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Rings%20and%20Rods.java) +150|[Implement Stack using Queues](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Implement%20Stack%20using%20Queues.java) +151|[Baseball Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Baseball%20Game.java) +152|[Pairs of Songs With Total Durations Divisible by 60](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Pairs%20of%20Songs%20With%20Total%20Durations%20Divisible%20by%2060.java) +153|[Destination City](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Destination%20City.java) +154|[Maximum Product of Three Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Product%20of%20Three%20Numbers.java) +155|[Three Consecutive Odds](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Three%20Consecutive%20Odds.java) +156|[Set Mismatch](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Set%20Mismatch.java) +157|[Sort Array by Increasing Frequency](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sort%20Array%20by%20Increasing%20Frequency.java) +158|[Find the Distance Value Between Two Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20Distance%20Value%20Between%20Two%20Arrays.java) +159|[Find Anagram Mappings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Anagram%20Mappings.java) +160|[Check if Array is Good](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20Array%20is%20Good.java) +161|[Decompress Run-Length Encoded List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Decompress%20Run-Length%20Encoded%20List.java) +162|[Flood Fill](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Flood%20Fill.java) +163|[Magic Squares In Grid](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Magic%20Squares%20In%20Grid.java) +164|[Smallest Even Multiple](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Smallest%20Even%20Multiple.java) +165|[Hexspeak](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Hexspeak.java) +166|[Diet Plan Performance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Diet%20Plan%20Performance.java) +167|[Maximum Number of Balloons](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Number%20of%20Balloons.java) +168|[Find Smallest Letter Greater Than Target](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Smallest%20Letter%20Greater%20Than%20Target.java) +169|[Check if Array Is Sorted and Rotated](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20Array%20Is%20Sorted%20and%20Rotated.java) +170|[Maximum Enemy Forts That Can Be Captured](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Enemy%20Forts%20That%20Can%20Be%20Captured.java) +171|[Path Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Path%20Sum.java) +172|[Day of the Year](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Day%20of%20the%20Year.java) +173|[Number of Beautiful Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Beautiful%20Pairs.java) +174|[Can Make Arithmetic Progression From Sequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Can%20Make%20Arithmetic%20Progression%20From%20Sequence.java) +175|[Furthest Point From Origin](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Furthest%20Point%20From%20Origin.java) +176|[Find the Highest Altitude](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20Highest%20Altitude.java) +177|[Root Equals Sum of Children](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Root%20Equals%20Sum%20of%20Children.java) +178|[Powerful Integers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Powerful%20Integers.java) +179|[Merge Two Sorted Lists](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Merge%20Two%20Sorted%20Lists.java) +180|[Binary Search](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Search.java) +181|[K-diff Pairs in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/K-diff%20Pairs%20in%20an%20Array.java) +182|[Repeated Substring Pattern](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Repeated%20Substring%20Pattern.java) +183|[Calculate Digit Sum of a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Calculate%20Digit%20Sum%20of%20a%20String.java) +184|[Reformat Phone Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reformat%20Phone%20Number.java) +185|[Longest Continuous Increasing Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Continuous%20Increasing%20Subsequence.java) +186|[Shuffle the Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Shuffle%20the%20Array.java) +187|[Count Pairs Of Similar Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Pairs%20Of%20Similar%20Strings.java) +188|[Ransom Note](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Ransom%20Note.java) +189|[trailing_zeroes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/trailing_zeroes.java) +190|[Height Checker](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Height%20Checker.java) +191|[License Key Formatting](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/License%20Key%20Formatting.java) +192|[Sum of Values at Indices With K Set Bits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20of%20Values%20at%20Indices%20With%20K%20Set%20Bits.java) +193|[Balanced Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Balanced%20Binary%20Tree.java) +194|[Check If It Is a Straight Line](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20If%20It%20Is%20a%20Straight%20Line.java) +195|[Binary Watch](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Watch.java) +196|[Count Special Quadruplets](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Special%20Quadruplets.java) +197|[Three Divisors](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Three%20Divisors.java) +198|[Make Array Zero by Subtracting Equal Amounts](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Make%20Array%20Zero%20by%20Subtracting%20Equal%20Amounts.java) +199|[Maximum Number of Words You Can Type](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Number%20of%20Words%20You%20Can%20Type.java) +200|[Contains Duplicate](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Contains%20Duplicate.java) +201|[Decode the Message](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Decode%20the%20Message.java) +202|[String Matching in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/String%20Matching%20in%20an%20Array.java) +203|[Count the Digits That Divide a Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20the%20Digits%20That%20Divide%20a%20Number.java) +204|[Distance Between Bus Stops](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Distance%20Between%20Bus%20Stops.java) +205|[Ugly Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Ugly%20Number.java) +206|[Faulty Keyboard](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Faulty%20Keyboard.java) +207|[Find the Pivot Integer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20Pivot%20Integer.java) +208|[Pascal's Triangle II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Pascal's%20Triangle%20II.java) +209|[Maximum Count of Positive Integer and Negative Integer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Count%20of%20Positive%20Integer%20and%20Negative%20Integer.java) +210|[Count Symmetric Integers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Symmetric%20Integers.java) +211|[Pascal's Triangle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Pascal's%20Triangle.java) +212|[Binary Prefix Divisible By 5](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Prefix%20Divisible%20By%205.java) +213|[Number Of Rectangles That Can Form The Largest Square](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20Of%20Rectangles%20That%20Can%20Form%20The%20Largest%20Square.java) +214|[Separate the Digits in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Separate%20the%20Digits%20in%20an%20Array.java) +215|[Count Negative Numbers in a Sorted Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Negative%20Numbers%20in%20a%20Sorted%20Matrix.java) +216|[Remove One Element to Make the Array Strictly Increasing](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20One%20Element%20to%20Make%20the%20Array%20Strictly%20Increasing.java) +217|[Two Furthest Houses With Different Colors](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Two%20Furthest%20Houses%20With%20Different%20Colors.java) +218|[Special Positions in a Binary Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Special%20Positions%20in%20a%20Binary%20Matrix.java) +219|[Check if All Characters Have Equal Number of Occurrences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20All%20Characters%20Have%20Equal%20Number%20of%20Occurrences.java) +220|[Valid Word Sequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Word%20Sequence.java) +221|[Counting Words With a Given Prefix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Counting%20Words%20With%20a%20Given%20Prefix.java) +222|[Binary Tree Inorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Tree%20Inorder%20Traversal.java) +223|[Minimum Moves to Convert String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Moves%20to%20Convert%20String.java) +224|[Design Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Design%20Linked%20List.java) +225|[Kth Distinct String in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Kth%20Distinct%20String%20in%20an%20Array.java) +226|[Count Good Triplets](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Good%20Triplets.java) +227|[Design an Ordered System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Design%20an%20Ordered%20System.java) +228|[Get Maximum in Generated Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Get%20Maximum%20in%20Generated%20Array.java) +229|[Convert the Temperature](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Convert%20the%20Temperature.java) +230|[Arranging Coins](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Arranging%20Coins.java) +231|[Count Pairs Whose Sum is Less than Target](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Pairs%20Whose%20Sum%20is%20Less%20than%20Target.java) +232|[Check if Word Equals Summation of Two Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20Word%20Equals%20Summation%20of%20Two%20Words.java) +233|[Fair Candy Swap](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Fair%20Candy%20Swap.java) +234|[Design Parking System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Design%20Parking%20System.java) +235|[Transpose Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Transpose%20Matrix.java) +236|[Delete Greatest Value in Each Row](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Delete%20Greatest%20Value%20in%20Each%20Row.java) +237|[Excel Sheet Column Title](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Excel%20Sheet%20Column%20Title.java) +238|[First Letter to Appear Twice](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/First%20Letter%20to%20Appear%20Twice.java) +239|[Linked List Cycle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Linked%20List%20Cycle.java) +240|[Find All the Lonely Nodes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20All%20the%20Lonely%20Nodes.java) +241|[Find the Maximum Achievable Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20Maximum%20Achievable%20Number.java) +242|[Base 7](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Base%207.java) +243|[Reverse Bits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20Bits.java) +244|[SqrtX](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/SqrtX.java) +245|[Check if Strings Can be Made Equal With Operations I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20Strings%20Can%20be%20Made%20Equal%20With%20Operations%20I.java) +246|[Similar RGB Color](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Similar%20RGB%20Color.java) +247|[Sort the People](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sort%20the%20People.java) +248|[Is Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Is%20Subsequence.java) +249|[Longest Even Odd Subarray With Threshold](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Even%20Odd%20Subarray%20With%20Threshold.java) +250|[Reverse Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20Linked%20List.java) +251|[Shortest Distance to a Character](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Shortest%20Distance%20to%20a%20Character.java) +252|[Count of Matches in Tournament](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20of%20Matches%20in%20Tournament.java) +253|[Valid Parentheses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Parentheses.java) +254|[Convert Sorted Array To Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Convert%20Sorted%20Array%20To%20Binary%20Search%20Tree.java) +255|[Count Vowel Substrings of a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Vowel%20Substrings%20of%20a%20String.java) +256|[Construct the rectangle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Construct%20the%20rectangle.java) +257|[Maximum Units on a Truck](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Units%20on%20a%20Truck.java) +258|[Sum of Left Leaves](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20of%20Left%20Leaves.java) +259|[Decrypt String from Alphabet to Integer Mapping](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Decrypt%20String%20from%20Alphabet%20to%20Integer%20Mapping.java) +260|[Number of Employees Who Met the Target](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Employees%20Who%20Met%20the%20Target.java) +261|[Find Pivot Index](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Pivot%20Index.java) +262|[Factorial Trailing Zeroes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Factorial%20Trailing%20Zeroes.java) +263|[Build an Array With Stack Operations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Build%20an%20Array%20With%20Stack%20Operations.java) +264|[Last Stone Weight](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Last%20Stone%20Weight.java) +265|[range_addition_II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/range_addition_II.java) +266|[Isomorphic Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Isomorphic%20Strings.java) +267|[Longest Subsequence With Limited Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Subsequence%20With%20Limited%20Sum.java) +268|[Split a String in Balanced Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Split%20a%20String%20in%20Balanced%20Strings.java) +269|[To Lower Case](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/To%20Lower%20Case.java) +270|[Sum of Digits of String After Convert](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20of%20Digits%20of%20String%20After%20Convert.java) +271|[Number of Senior Citizens](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Senior%20Citizens.java) +272|[Minimum Cost to Move Chips to The Same Position](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Cost%20to%20Move%20Chips%20to%20The%20Same%20Position.java) +273|[Read N characters Given Read4](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Read%20N%20characters%20Given%20Read4.java) +274|[Longest Alternating Subarray](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Alternating%20Subarray.java) +275|[Delete N Nodes After M Nodes of a Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Delete%20N%20Nodes%20After%20M%20Nodes%20of%20a%20Linked%20List.java) +276|[Count Items Matching a Rule](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Items%20Matching%20a%20Rule.java) +277|[Reverse Vowels of a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20Vowels%20of%20a%20String.java) +278|[Largest Local Values in a Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Largest%20Local%20Values%20in%20a%20Matrix.java) +279|[A Number After a Double Reversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/A%20Number%20After%20a%20Double%20Reversal.java) +280|[Roman to Integer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Roman%20to%20Integer.java) +281|[Cousins in Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Cousins%20in%20Binary%20Tree.java) +282|[Binary Tree Paths](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Tree%20Paths.java) +283|[Complement of Base 10 Integer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Complement%20of%20Base%2010%20Integer.java) +284|[Find if Path Exists in Graph](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20if%20Path%20Exists%20in%20Graph.java) +285|[Minimum Difference Between Highest and Lowest of K Scores](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Difference%20Between%20Highest%20and%20Lowest%20of%20K%20Scores.java) +286|[Number of Days in a Month](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Days%20in%20a%20Month.java) +287|[Find Resultant Array After Removing Anagrams](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Resultant%20Array%20After%20Removing%20Anagrams.java) +288|[Minimum String Length After Removing Substrings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20String%20Length%20After%20Removing%20Substrings.java) +289|[Palindrome Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Palindrome%20Number.java) +290|[Find Subarrays With Equal Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Subarrays%20With%20Equal%20Sum.java) +291|[Account Balance After Rounded Purchase](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Account%20Balance%20After%20Rounded%20Purchase.java) +292|[Minimum Amount of Time to Fill Cups](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Amount%20of%20Time%20to%20Fill%20Cups.java) +293|[Detect Pattern of Length M Repeated K or More Times](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Detect%20Pattern%20of%20Length%20M%20Repeated%20K%20or%20More%20Times.java) +294|[Largest Positive Integer That Exists With Its Negative](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Largest%20Positive%20Integer%20That%20Exists%20With%20Its%20Negative.java) +295|[Univalued Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Univalued%20Binary%20Tree.java) +296|[Single-Row Keyboard](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Single-Row%20Keyboard.java) +297|[Remove Linked List Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20Linked%20List%20Elements.java) +298|[How Many Numbers Are Smaller Than the Current Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/How%20Many%20Numbers%20Are%20Smaller%20Than%20the%20Current%20Number.java) +299|[Most Frequent Even Element](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Most%20Frequent%20Even%20Element.java) +300|[Maximum Odd Binary Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Odd%20Binary%20Number.java) +301|[Armstrong Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Armstrong%20Number.java) +302|[Counting Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Counting%20Elements.java) +303|[Make The String Great](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Make%20The%20String%20Great.java) +304|[Cells with Odd Values in a Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Cells%20with%20Odd%20Values%20in%20a%20Matrix.java) +305|[Power of Two](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Power%20of%20Two.java) +306|[Decode XORed Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Decode%20XORed%20Array.java) +307|[Long Pressed Name](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Long%20Pressed%20Name.java) +308|[Kids With the Greatest Number of Candies](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Kids%20With%20the%20Greatest%20Number%20of%20Candies.java) +309|[N-ary Tree Postorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/N-ary%20Tree%20Postorder%20Traversal.java) +310|[Max Consecutive Ones](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Max%20Consecutive%20Ones.java) +311|[Find Words That Can Be Formed by Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Words%20That%20Can%20Be%20Formed%20by%20Characters.java) +312|[Number of 1 bits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%201%20bits.java) +313|[Largest Unique Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Largest%20Unique%20Number.java) +314|[The Employee That Worked on the Longest Task](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/The%20Employee%20That%20Worked%20on%20the%20Longest%20Task.java) +315|[Paint House](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Paint%20House.java) +316|[Logger Rate Limiter](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Logger%20Rate%20Limiter.java) +317|[Substrings of Size Three with Distinct Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Substrings%20of%20Size%20Three%20with%20Distinct%20Characters.java) +318|[Maximum Difference by Remapping a Digit](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Difference%20by%20Remapping%20a%20Digit.java) +319|[Monotonic Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Monotonic%20Array.java) +320|[Check if One String Swap Can Make Strings Equal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20One%20String%20Swap%20Can%20Make%20Strings%20Equal.java) +321|[Valid Palindrome II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Palindrome%20II.java) +322|[Occurrences After Bigram](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Occurrences%20After%20Bigram.java) +323|[Minimum Sum of Four Digit Number After Splitting Digits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Sum%20of%20Four%20Digit%20Number%20After%20Splitting%20Digits.java) +324|[Move Zeroes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Move%20Zeroes.java) +325|[Number of Arithmetic Triplets](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Arithmetic%20Triplets.java) +326|[Count Number of Pairs With Absolute Difference K](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Number%20of%20Pairs%20With%20Absolute%20Difference%20K.java) +327|[Number of Lines To Write String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Lines%20To%20Write%20String.java) +328|[First Unique Character in a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/First%20Unique%20Character%20in%20a%20String.java) +329|[Maximum depth of Binary tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20depth%20of%20Binary%20tree.java) +330|[Largest Number At Least Twice of Others](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Largest%20Number%20At%20Least%20Twice%20of%20Others.java) +331|[Reverse String II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20String%20II.java) +332|[Letter Case Permutation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Letter%20Case%20Permutation.java) +333|[Two Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Two%20Sum.java) +334|[Climbing Stairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Climbing%20Stairs.java) +335|[Projection Area of 3D Shapes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Projection%20Area%20of%203D%20Shapes.java) +336|[Maximize Sum Of Array After K Negations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximize%20Sum%20Of%20Array%20After%20K%20Negations.java) +337|[Third Maximum Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Third%20Maximum%20Number.java) +338|[Sign of the Product of an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sign%20of%20the%20Product%20of%20an%20Array.java) +339|[Heaters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Heaters.java) +340|[Remove Palindromic Subsequences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20Palindromic%20Subsequences.java) +341|[Time Needed to Buy Tickets](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Time%20Needed%20to%20Buy%20Tickets.java) +342|[Find the K-Beauty of a Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20K-Beauty%20of%20a%20Number.java) +343|[Find All K-Distant Indices in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20All%20K-Distant%20Indices%20in%20an%20Array.java) +344|[Student Attendance Record I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Student%20Attendance%20Record%20I.java) +345|[Delete Characters to Make Fancy String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Delete%20Characters%20to%20Make%20Fancy%20String.java) +346|[Longest Uncommon Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Uncommon%20Subsequence.java) +347|[Check Distances Between Same Letters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20Distances%20Between%20Same%20Letters.java) +348|[Valid Mountain Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Mountain%20Array.java) +349|[Shortest Word Distance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Shortest%20Word%20Distance.java) +350|[Check if String Is Decomposable Into Value-Equal Substrings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20String%20Is%20Decomposable%20Into%20Value-Equal%20Substrings.java) +351|[Matrix Cells in Distance Order](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Matrix%20Cells%20in%20Distance%20Order.java) +352|[Final Value of Variable After Performing Operations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Final%20Value%20of%20Variable%20After%20Performing%20Operations.java) +353|[Shuffle String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Shuffle%20String.java) +354|[Sum of Square Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20of%20Square%20Numbers.java) +355|[Percentage of Letter in String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Percentage%20of%20Letter%20in%20String.java) +356|[Intersection of Two Arrays II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Intersection%20of%20Two%20Arrays%20II.java) +357|[Most Common Word](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Most%20Common%20Word.java) +358|[Count Asterisks](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Asterisks.java) +359|[Sum of Squares of Special Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20of%20Squares%20of%20Special%20Elements.java) +360|[Largest 3-Same-Digit Number in String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Largest%203-Same-Digit%20Number%20in%20String.java) +361|[Number of Students Doing Homework at a Given Time](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Students%20Doing%20Homework%20at%20a%20Given%20Time.java) +362|[Invert Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Invert%20Binary%20Tree.java) +363|[Check if the Sentence Is Pangram](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20the%20Sentence%20Is%20Pangram.java) +364|[Island Perimeter](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Island%20Perimeter.java) +365|[Available Captures for Rook](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Available%20Captures%20for%20Rook.java) +366|[Count Common Words With One Occurrence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Common%20Words%20With%20One%20Occurrence.java) +367|[Degree of an array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Degree%20of%20an%20array.java) +368|[Sum of Root To Leaf Binary Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20of%20Root%20To%20Leaf%20Binary%20Numbers.java) +369|[Circular Sentence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Circular%20Sentence.java) +370|[Sort Array By Parity](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sort%20Array%20By%20Parity.java) +371|[Number of Good Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Good%20Pairs.java) +372|[Convert a number to hexadecimal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Convert%20a%20number%20to%20hexadecimal.java) +373|[Check If a Word Occurs As a Prefix of Any Word in a Sentence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20If%20a%20Word%20Occurs%20As%20a%20Prefix%20of%20Any%20Word%20in%20a%20Sentence.java) +374|[Calculate Delayed Arrival Time](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Calculate%20Delayed%20Arrival%20Time.java) +375|[Concatenation of Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Concatenation%20of%20Array.java) +376|[Number of Recent Calls](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Recent%20Calls.java) +377|[Fixed Point](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Fixed%20Point.java) +378|[Valid Boomerang](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Boomerang.java) +379|[Minimum Moves to Equal an Array Element](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Moves%20to%20Equal%20an%20Array%20Element.java) +380|[Calculate Money in Leetcode Bank](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Calculate%20Money%20in%20Leetcode%20Bank.java) +381|[Check If Two String Arrays are Equivalent](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20If%20Two%20String%20Arrays%20are%20Equivalent.java) +382|[Find Nearest Point That Has the Same X or Y Coordinate](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Nearest%20Point%20That%20Has%20the%20Same%20X%20or%20Y%20Coordinate.java) +383|[Maximum Product Difference Between Two Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Product%20Difference%20Between%20Two%20Pairs.java) +384|[Goal Parser Interpretation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Goal%20Parser%20Interpretation.java) +385|[Find the Losers of the Circular Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20Losers%20of%20the%20Circular%20Game.java) +386|[Judge Route Cycle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Judge%20Route%20Cycle.java) +387|[K Items With the Maximum Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/K%20Items%20With%20the%20Maximum%20Sum.java) +388|[Middle of the linked list](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Middle%20of%20the%20linked%20list.java) +389|[Maximum Number of Pairs in Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Number%20of%20Pairs%20in%20Array.java) +390|[Check if Matrix Is X-Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20Matrix%20Is%20X-Matrix.java) +391|[Compare Strings by Frequency of the Smallest Character](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Compare%20Strings%20by%20Frequency%20of%20the%20Smallest%20Character.java) +392|[Intersection of Two Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Intersection%20of%20Two%20Arrays.java) +393|[Bulls and Cows](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Bulls%20and%20Cows.java) +394|[Slowest Key](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Slowest%20Key.java) +395|[Count Equal and Divisible Pairs in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Equal%20and%20Divisible%20Pairs%20in%20an%20Array.java) +396|[nim_game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/nim_game.java) +397|[Min Max Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Min%20Max%20Game.java) +398|[Groups of Special-Equivalent Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Groups%20of%20Special-Equivalent%20Strings.java) +399|[Reformat The String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reformat%20The%20String.java) +400|[Minimum Number of Operations to Convert Time](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Number%20of%20Operations%20to%20Convert%20Time.java) +401|[Form Smallest Number From Two Digit Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Form%20Smallest%20Number%20From%20Two%20Digit%20Arrays.java) +402|[Minimum Operations to Collect Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Operations%20to%20Collect%20Elements.java) +403|[Count Elements With Strictly Smaller and Greater Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Elements%20With%20Strictly%20Smaller%20and%20Greater%20Elements.java) +404|[Determine the Winner of a Bowling Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Determine%20the%20Winner%20of%20a%20Bowling%20Game.java) +405|[Minimum Operations to Make the Array Increasing](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Operations%20to%20Make%20the%20Array%20Increasing.java) +406|[Minimum Right Shifts to Sort the Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Right%20Shifts%20to%20Sort%20the%20Array.java) +407|[Index Pairs of a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Index%20Pairs%20of%20a%20String.java) +408|[Number of Steps to Reduce a Number to Zero](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Steps%20to%20Reduce%20a%20Number%20to%20Zero.java) +409|[Confusing Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Confusing%20Number.java) +410|[Convert BST to Greater Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Convert%20BST%20to%20Greater%20Tree.java) +411|[Find All Numbers Disappeared in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20All%20Numbers%20Disappeared%20in%20an%20Array.java) +412|[Largest Number After Digit Swaps by Parity](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Largest%20Number%20After%20Digit%20Swaps%20by%20Parity.java) +413|[Merge Two 2D Arrays by Summing Values](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Merge%20Two%202D%20Arrays%20by%20Summing%20Values.java) +414|[Reformat Date](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reformat%20Date.java) +415|[Largest Odd Number in String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Largest%20Odd%20Number%20in%20String.java) +416|[Build Array from Permutation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Build%20Array%20from%20Permutation.java) +417|[Find Lucky Integer in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Lucky%20Integer%20in%20an%20Array.java) +418|[Reverse Prefix of Word](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20Prefix%20of%20Word.java) +419|[Nested List Weight Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Nested%20List%20Weight%20Sum.java) +420|[Relative ranks](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Relative%20ranks.java) +421|[Palindrome Permutation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Palindrome%20Permutation.java) +422|[Find Winner on a Tic Tac Toe Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Winner%20on%20a%20Tic%20Tac%20Toe%20Game.java) +423|[Merge two binary trees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Merge%20two%20binary%20trees.java) +424|[Check if Numbers Are Ascending in a Sentence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20Numbers%20Are%20Ascending%20in%20a%20Sentence.java) +425|[Power of Three](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Power%20of%20Three.java) +426|[Remove Letter To Equalize Frequency](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20Letter%20To%20Equalize%20Frequency.java) +427|[Lemonade Change](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Lemonade%20Change.java) +428|[Length of last word](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Length%20of%20last%20word.java) +429|[Increasing Decreasing String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Increasing%20Decreasing%20String.java) +430|[N-th Tribonacci Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/N-th%20Tribonacci%20Number.java) +431|[Longest Common Prefix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Common%20Prefix.java) +432|[Minimum Time Visiting All Points](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Time%20Visiting%20All%20Points.java) +433|[Calculate Amount Paid in Taxes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Calculate%20Amount%20Paid%20in%20Taxes.java) +434|[Number of Different Integers in a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Different%20Integers%20in%20a%20String.java) +435|[Minimize String Length](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimize%20String%20Length.java) +436|[Add Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Add%20Strings.java) +437|[Maximum Ascending Subarray Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Ascending%20Subarray%20Sum.java) +438|[Best Time to Buy and Sell Stock](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Best%20Time%20to%20Buy%20and%20Sell%20Stock.java) +439|[Lowest Common Ancestor of a Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Lowest%20Common%20Ancestor%20of%20a%20Binary%20Search%20Tree.java) +440|[Determine if String Halves Are Alike](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Determine%20if%20String%20Halves%20Are%20Alike.java) +441|[Find the difference](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20difference.java) +442|[Check if Every Row and Column Contains All Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20Every%20Row%20and%20Column%20Contains%20All%20Numbers.java) +443|[Replace All Digits with Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Replace%20All%20Digits%20with%20Characters.java) +444|[Largest Substring Between Two Equal Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Largest%20Substring%20Between%20Two%20Equal%20Characters.java) +445|[Strobogrammatic Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Strobogrammatic%20Number.java) +446|[Rearrange Characters to Make Target String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Rearrange%20Characters%20to%20Make%20Target%20String.java) +447|[Next Greater Element I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Next%20Greater%20Element%20I.java) +448|[Counting Bits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Counting%20Bits.java) +449|[Remove Outermost Parentheses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20Outermost%20Parentheses.java) +450|[Count the Number of Vowel Strings in Range](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20the%20Number%20of%20Vowel%20Strings%20in%20Range.java) +451|[Determine if Two Events Have Conflict](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Determine%20if%20Two%20Events%20Have%20Conflict.java) +452|[Replace All ?'s to Avoid Consecutive Repeating Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Replace%20All%20?'s%20to%20Avoid%20Consecutive%20Repeating%20Characters.java) +453|[Two Sum Less Than K](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Two%20Sum%20Less%20Than%20K.java) +454|[Majority Element](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Majority%20Element.java) +455|[Merge Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Merge%20Sorted%20Array.java) +456|[Unique Morse Code Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Unique%20Morse%20Code%20Words.java) +457|[Divisor Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Divisor%20Game.java) +458|[Find Numbers with Even Number of Digits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Numbers%20with%20Even%20Number%20of%20Digits.java) +459|[Categorize Box According to Criteria](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Categorize%20Box%20According%20to%20Criteria.java) +460|[Implement Queue using Stacks](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Implement%20Queue%20using%20Stacks.java) +461|[N-ary Tree Preorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/N-ary%20Tree%20Preorder%20Traversal.java) +462|[Smallest Index With Equal Value](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Smallest%20Index%20With%20Equal%20Value.java) +463|[Total Distance Traveled](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Total%20Distance%20Traveled.java) +464|[Delete Node in a Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Delete%20Node%20in%20a%20Linked%20List.java) +465|[Sort Array By Parity II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sort%20Array%20By%20Parity%20II.java) +466|[Most Visited Sector in a Circular Track](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Most%20Visited%20Sector%20in%20a%20Circular%20Track.java) +467|[Greatest Common Divisor of Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Greatest%20Common%20Divisor%20of%20Strings.java) +468|[Remove Element](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20Element.java) +469|[Maximum Subarray Sum I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Subarray%20Sum%20I.java) +470|[Partition Array Into Three Parts With Equal Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Partition%20Array%20Into%20Three%20Parts%20With%20Equal%20Sum.java) +471|[Remove Duplicates From Sorted Lists](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20Duplicates%20From%20Sorted%20Lists.java) +472|[Minimum Bit Flips to Convert Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Bit%20Flips%20to%20Convert%20Number.java) +473|[Sort Even and Odd Indices Independently](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sort%20Even%20and%20Odd%20Indices%20Independently.java) +474|[Meeting Rooms](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Meeting%20Rooms.java) +475|[Crawler Log Folder](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Crawler%20Log%20Folder.java) +476|[Maximum Difference Between Increasing Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Difference%20Between%20Increasing%20Elements.java) +477|[Left and Right Sum Differences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Left%20and%20Right%20Sum%20Differences.java) +478|[Find the Middle Index in Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20Middle%20Index%20in%20Array.java) +479|[Range Sum Query Immutable](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Range%20Sum%20Query%20Immutable.java) +480|[Intersection of two Linked Lists](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Intersection%20of%20two%20Linked%20Lists.java) +481|[Merge Similar Items](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Merge%20Similar%20Items.java) +482|[Can Place Flowers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Can%20Place%20Flowers.java) +483|[Generate a String With Characters That Have Odd Counts](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Generate%20a%20String%20With%20Characters%20That%20Have%20Odd%20Counts.java) +484|[Count Operations to Obtain Zero](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Operations%20to%20Obtain%20Zero.java) +485|[Array Partition I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Array%20Partition%20I.java) +486|[Next Greater Element](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Next%20Greater%20Element.java) +487|[Perfect Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Perfect%20Number.java) +488|[Sum of Digits in the Minimum Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20of%20Digits%20in%20the%20Minimum%20Number.java) +489|[Guess Number Higher or Lower](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Guess%20Number%20Higher%20or%20Lower.java) +490|[Find the Array Concatenation Value](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20Array%20Concatenation%20Value.java) +491|[Self Dividing Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Self%20Dividing%20Number.java) +492|[Design HashMap](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Design%20HashMap.java) +493|[Minimum Time to Type Word Using Special Typewriter](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Time%20to%20Type%20Word%20Using%20Special%20Typewriter.java) +494|[Check Whether Two Strings are Almost Equivalent](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20Whether%20Two%20Strings%20are%20Almost%20Equivalent.java) +495|[Shortest Distance to Target String in a Circular Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Shortest%20Distance%20to%20Target%20String%20in%20a%20Circular%20Array.java) +496|[Cells in a Range on an Excel Sheet](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Cells%20in%20a%20Range%20on%20an%20Excel%20Sheet.java) +497|[Number of Common Factors](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Common%20Factors.java) +498|[Keep Multiplying Found Values by Two](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Keep%20Multiplying%20Found%20Values%20by%20Two.java) +499|[Search in a Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Search%20in%20a%20Binary%20Search%20Tree.java) +500|[Count Largest Group](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Largest%20Group.java) +501|[Sum of Unique Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20of%20Unique%20Elements.java) +502|[Moving Average from Data Stream](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Moving%20Average%20from%20Data%20Stream.java) +503|[Symmetric Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Symmetric%20Tree.java) +504|[Maximum Product of Two Elements in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Product%20of%20Two%20Elements%20in%20an%20Array.java) +505|[Difference Between Element Sum and Digit Sum of an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Difference%20Between%20Element%20Sum%20and%20Digit%20Sum%20of%20an%20Array.java) +506|[Find Common Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Common%20Characters.java) +507|[Lucky Numbers in a Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Lucky%20Numbers%20in%20a%20Matrix.java) +508|[Remove Vowels from a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20Vowels%20from%20a%20String.java) +509|[Add Digits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Add%20Digits.java) +510|[Teemo Attacking](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Teemo%20Attacking.java) +511|[Contains Duplicate II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Contains%20Duplicate%20II.java) +512|[Count Integers With Even Digit Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Integers%20With%20Even%20Digit%20Sum.java) +513|[Minimum Index Sum of Two Lists](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Index%20Sum%20of%20Two%20Lists.java) +514|[Two Out of Three](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Two%20Out%20of%20Three.java) +515|[Closest Binary Search Tree Value](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Closest%20Binary%20Search%20Tree%20Value.java) +516|[Distribute Money to Maximum Children](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Distribute%20Money%20to%20Maximum%20Children.java) +517|[Sum of Digits in Base K](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20of%20Digits%20in%20Base%20K.java) +518|[Fibonacci Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Fibonacci%20Number.java) +519|[Distribute Candies to People](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Distribute%20Candies%20to%20People.java) +520|[Valid Word Square](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Word%20Square.java) +521|[Distribute Candies](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Distribute%20Candies.java) +522|[Check If a Number Is Majority Element in a Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20If%20a%20Number%20Is%20Majority%20Element%20in%20a%20Sorted%20Array.java) +523|[Alternating Digit Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Alternating%20Digit%20Sum.java) +524|[Take Gifts From the Richest Pile](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Take%20Gifts%20From%20the%20Richest%20Pile.java) +525|[Verifying an Alien Dictionary](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Verifying%20an%20Alien%20Dictionary.java) +526|[Longest Palindrome](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Palindrome.java) +527|[Sum of All Odd Length Subarrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20of%20All%20Odd%20Length%20Subarrays.java) +528|[Average Salary Excluding the Minimum and Maximum Salary](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Average%20Salary%20Excluding%20the%20Minimum%20and%20Maximum%20Salary.java) +529|[Apply Operations to an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Apply%20Operations%20to%20an%20Array.java) +530|[Single Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Single%20Number.java) +531|[Keyboard Row](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Keyboard%20Row.java) +532|[Count Distinct Numbers on Board](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Distinct%20Numbers%20on%20Board.java) +533|[Squares of a Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Squares%20of%20a%20Sorted%20Array.java) +534|[Find the Longest Balanced Substring of a Binary String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20Longest%20Balanced%20Substring%20of%20a%20Binary%20String.java) +535|[Binary Tree Postorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Binary%20Tree%20Postorder%20Traversal.java) +536|[Rearrange Spaces Between Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Rearrange%20Spaces%20Between%20Words.java) +537|[Minimum Recolors to Get K Consecutive Black Blocks](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Recolors%20to%20Get%20K%20Consecutive%20Black%20Blocks.java) +538|[Count Square Sum Triples](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Square%20Sum%20Triples.java) +539|[Maximum Distance in Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Distance%20in%20Arrays.java) +540|[Unique Number of Occurrences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Unique%20Number%20of%20Occurrences.java) +541|[Day of the Week](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Day%20of%20the%20Week.java) +542|[Design an Ordered Stream](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Design%20an%20Ordered%20Stream.java) +543|[Minimum Distance Between BST Nodes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Distance%20Between%20BST%20Nodes.java) +544|[Maximum Sum With Exactly K Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Sum%20With%20Exactly%20K%20Elements.java) +545|[Number of Students Unable to Eat Lunch](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Number%20of%20Students%20Unable%20to%20Eat%20Lunch.java) +546|[Check if Number Has Equal Digit Count and Digit Value](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20Number%20Has%20Equal%20Digit%20Count%20and%20Digit%20Value.java) +547|[Sum Of Two Integers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sum%20Of%20Two%20Integers.java) +548|[Check if a String Is an Acronym of Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20if%20a%20String%20Is%20an%20Acronym%20of%20Words.java) +549|[Search Insert Position](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Search%20Insert%20Position.java) +550|[Max Pair Sum in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Max%20Pair%20Sum%20in%20an%20Array.java) +551|[Longest Univalue Path](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Univalue%20Path.java) +552|[Maximum Depth of N-ary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Depth%20of%20N-ary%20Tree.java) +553|[Thousand Separator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Thousand%20Separator.java) +554|[Add Binary](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Add%20Binary.java) +555|[Convert Binary Number in a Linked List to Integer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Convert%20Binary%20Number%20in%20a%20Linked%20List%20to%20Integer.java) +556|[Sorting the Sentence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sorting%20the%20Sentence.java) +557|[Replace Elements with Greatest Element on Right Side](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Replace%20Elements%20with%20Greatest%20Element%20on%20Right%20Side.java) +558|[Matrix Diagonal Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Matrix%20Diagonal%20Sum.java) +559|[Check Array Formation Through Concatenation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Check%20Array%20Formation%20Through%20Concatenation.java) +560|[Water Bottles](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Water%20Bottles.java) +561|[Add to Array-Form of Integer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Add%20to%20Array-Form%20of%20Integer.java) +562|[Prime In Diagonal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Prime%20In%20Diagonal.java) +563|[Pass the Pillow](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Pass%20the%20Pillow.java) +564|[Missing Number In Arithmetic Progression](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Missing%20Number%20In%20Arithmetic%20Progression.java) +565|[Divide Array Into Equal Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Divide%20Array%20Into%20Equal%20Pairs.java) +566|[Maximum Value of a String in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Value%20of%20a%20String%20in%20an%20Array.java) +567|[Maximum Number of Balls in a Box](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Number%20of%20Balls%20in%20a%20Box.java) +568|[Mean of Array After Removing Some Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Mean%20of%20Array%20After%20Removing%20Some%20Elements.java) +569|[N-Repeated Element in Size 2N Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/N-Repeated%20Element%20in%20Size%202N%20Array.java) +570|[Redistribute Characters to Make All Strings Equal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Redistribute%20Characters%20to%20Make%20All%20Strings%20Equal.java) +571|[Remove All Adjacent Duplicates In String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Remove%20All%20Adjacent%20Duplicates%20In%20String.java) +572|[Minimum Absolute Difference in BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20%20Absolute%20Difference%20in%20BST.java) +573|[Image Smoother](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Image%20Smoother.java) +574|[Find the Difference of Two Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20the%20Difference%20of%20Two%20Arrays.java) +575|[How Many Apples Can You Put into the Basket](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/How%20Many%20Apples%20Can%20You%20Put%20into%20the%20Basket.java) +576|[Second Minimum Node in a binary tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Second%20Minimum%20Node%20in%20a%20binary%20tree.java) +577|[Excel Sheet Column Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Excel%20Sheet%20Column%20Number.java) +578|[Same Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Same%20Tree.java) +579|[Count Odd Numbers in an Interval Range](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Odd%20Numbers%20in%20an%20Interval%20Range.java) +580|[String Without AAA or BBB](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/String%20Without%20AAA%20or%20BBB.java) +581|[Find Greatest Common Divisor of Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Greatest%20Common%20Divisor%20of%20Array.java) +582|[Longest Word in Dictionary](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Longest%20Word%20in%20Dictionary.java) +583|[Happy Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Happy%20Number.java) +584|[Array Transformation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Array%20Transformation.java) +585|[Design Compressed String Iterator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Design%20Compressed%20String%20Iterator.java) +586|[Reverse words in a String III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Reverse%20words%20in%20a%20String%20III.java) +587|[Rank Transform of an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Rank%20Transform%20of%20an%20Array.java) +588|[First Bad Version](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/First%20Bad%20Version.java) +589|[Sort Integers by The Number of 1 Bits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Sort%20Integers%20by%20The%20Number%20of%201%20Bits.java) +590|[Split With Minimum Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Split%20With%20Minimum%20Sum.java) +591|[Construct String from Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Construct%20String%20from%20Binary%20Tree.java) +592|[Maximum Number of Words Found in Sentences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Maximum%20Number%20of%20Words%20Found%20in%20Sentences.java) +593|[Toeplitz Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Toeplitz%20Matrix.java) +594|[Find Maximum Number of String Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Find%20Maximum%20Number%20of%20String%20Pairs.java) +595|[Finding 3-Digit Even Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Finding%203-Digit%20Even%20Numbers.java) +596|[Valid Word Abbreviation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Word%20Abbreviation.java) +597|[Second Largest Digit in a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Second%20Largest%20Digit%20in%20a%20String.java) +598|[Valid Palindrome](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Valid%20Palindrome.java) +599|[Relative Sort Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Relative%20Sort%20Array.java) +600|[Minimum Cuts to Divide a Circle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Minimum%20Cuts%20to%20Divide%20a%20Circle.java) +601|[Path In Zigzag Labelled Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Path%20In%20Zigzag%20Labelled%20Binary%20Tree.java) +602|[Shortest Completing Word](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Shortest%20Completing%20Word.java) +603|[Nim Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Nim%20Game.java) +604|[Count Substrings with Only One Distinct Letter](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Count%20Substrings%20with%20Only%20One%20Distinct%20Letter.java) +605|[Average of Levels in Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Average%20of%20Levels%20in%20Binary%20Tree.java) +606|[Merge Strings Alternately](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Easy/Merge%20Strings%20Alternately.java) diff --git a/Easy/Range Sum Query Immutable.java b/Easy/Range Sum Query Immutable.java new file mode 100644 index 00000000..5318818c --- /dev/null +++ b/Easy/Range Sum Query Immutable.java @@ -0,0 +1,23 @@ +class NumArray { + + int[] sumArray; + + public NumArray(int[] nums) { + sumArray = new int[nums.length]; + int currSum = 0; + for (int i = 0; i < nums.length; i++) { + currSum += nums[i]; + sumArray[i] = currSum; + } + } + + public int sumRange(int left, int right) { + return sumArray[right] - (left == 0 ? 0 : sumArray[left - 1]); + } +} + +/** + * Your NumArray object will be instantiated and called as such: + * NumArray obj = new NumArray(nums); + * int param_1 = obj.sumRange(left,right); + */ diff --git a/Easy/Range Sum Query_Immutable.java b/Easy/Range Sum Query_Immutable.java deleted file mode 100644 index 9a5b7fc8..00000000 --- a/Easy/Range Sum Query_Immutable.java +++ /dev/null @@ -1,26 +0,0 @@ -class NumArray { - int[] cumulativeSum; - int n; - public NumArray(int[] nums) { - n = nums.length; - cumulativeSum = new int[n]; - int currSum = 0; - for (int i = 0; i < n; i++) { - currSum += nums[i]; - cumulativeSum[i] = currSum; - } - } - - public int sumRange(int i, int j) { - if (i == 0) { - return cumulativeSum[j]; - } - return cumulativeSum[j] - cumulativeSum[i - 1]; - } -} - -/** - * Your NumArray object will be instantiated and called as such: - * NumArray obj = new NumArray(nums); - * int param_1 = obj.sumRange(i,j); - */ diff --git a/Easy/Range Sum of BST.java b/Easy/Range Sum of BST.java new file mode 100644 index 00000000..3ed8dfdd --- /dev/null +++ b/Easy/Range Sum of BST.java @@ -0,0 +1,35 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public int rangeSumBST(TreeNode root, int low, int high) { + int sum = 0; + Queue queue = new LinkedList<>(); + queue.add(root); + while (!queue.isEmpty()) { + TreeNode removed = queue.remove(); + if (removed.val >= low && removed.val <= high) { + sum += removed.val; + } + if (removed.val >= low && removed.left != null) { + queue.add(removed.left); + } + if (removed.val <= high && removed.right != null) { + queue.add(removed.right); + } + } + return sum; + } +} diff --git a/Easy/Rank Transform of an Array.java b/Easy/Rank Transform of an Array.java index 951115ae..3f9192fd 100644 --- a/Easy/Rank Transform of an Array.java +++ b/Easy/Rank Transform of an Array.java @@ -1,20 +1,19 @@ class Solution { - public int[] arrayRankTransform(int[] arr) { - PriorityQueue pq = Arrays.stream(arr).boxed() - .collect(Collectors.toCollection(PriorityQueue::new)); - int rank = 1; - Map rankMap = new HashMap<>(); - while (!pq.isEmpty()) { - int key = pq.poll(); - rankMap.put(key, rank++); - while (!pq.isEmpty() && pq.peek() == key) { - pq.poll(); - } + public int[] arrayRankTransform(int[] arr) { + int[] copyArr = Arrays.copyOf(arr, arr.length); + Arrays.sort(arr); + int rank = 1; + Map numToRank = new HashMap<>(); + for (int num : arr) { + if (numToRank.containsKey(num)) { + continue; + } + numToRank.put(num, rank++); + } + int[] result = new int[arr.length]; + for (int i = 0; i < arr.length; i++) { + result[i] = numToRank.get(copyArr[i]); + } + return result; } - int[] ans = new int[arr.length]; - for (int i = 0; i < arr.length; i++) { - ans[i] = rankMap.get(arr[i]); - } - return ans; - } } diff --git a/Easy/Read N characters Given Read4.java b/Easy/Read N characters Given Read4.java index 2ba3d5a6..d8507075 100644 --- a/Easy/Read N characters Given Read4.java +++ b/Easy/Read N characters Given Read4.java @@ -1,6 +1,6 @@ /** * The read4 API is defined in the parent class Reader4. - * int read4(char[] buf); + * int read4(char[] buf4); */ public class Solution extends Reader4 { @@ -10,17 +10,19 @@ public class Solution extends Reader4 { * @return The number of actual characters read */ public int read(char[] buf, int n) { - boolean endOfFile = false; - int totalLength = 0; - char[] temp = new char[4]; - while (!endOfFile && totalLength < n) { - int count = read4(temp); - endOfFile = count < 4; - count = Math.min(count, n - totalLength); - for (int i = 0; i < count; i++) { - buf[totalLength++] = temp[i]; + int copied = 0; + int readLength = 4; + char[] buf4 = new char[4]; + while (copied < n && readLength == 4) { + readLength = read4(buf4); + for (int i = 0; i < readLength; i++) { + if (copied == n) { + return copied; + } + buf[copied] = buf4[i]; + copied++; } } - return totalLength; + return copied; } } diff --git a/Easy/Rearrange Characters to Make Target String.java b/Easy/Rearrange Characters to Make Target String.java new file mode 100644 index 00000000..352e45f9 --- /dev/null +++ b/Easy/Rearrange Characters to Make Target String.java @@ -0,0 +1,17 @@ +class Solution { + public int rearrangeCharacters(String s, String target) { + int[] frequencyS = new int[26]; + int[] frequencyTarget = new int[26]; + for(char ch : s.toCharArray()) { + frequencyS[ch-'a']++; + } + for(char ch : target.toCharArray()) { + frequencyTarget[ch-'a']++; + } + int maxCopies = Integer.MAX_VALUE; + for(char ch : target.toCharArray()) { + maxCopies = Math.min(maxCopies, frequencyS[ch - 'a'] / frequencyTarget[ch - 'a']); + } + return maxCopies; + } +} diff --git a/Easy/Rectangle Overlap.java b/Easy/Rectangle Overlap.java new file mode 100644 index 00000000..cd471934 --- /dev/null +++ b/Easy/Rectangle Overlap.java @@ -0,0 +1,6 @@ +class Solution { + public boolean isRectangleOverlap(int[] rec1, int[] rec2) { + return (Math.min(rec1[2], rec2[2]) > Math.max(rec1[0], rec2[0]) && + Math.min(rec1[3], rec2[3]) > Math.max(rec1[1], rec2[1])); + } +} diff --git a/Easy/Redistribute Characters to Make All Strings Equal.java b/Easy/Redistribute Characters to Make All Strings Equal.java new file mode 100644 index 00000000..e034cce7 --- /dev/null +++ b/Easy/Redistribute Characters to Make All Strings Equal.java @@ -0,0 +1,10 @@ +class Solution { + public boolean makeEqual(String[] words) { + return Arrays.stream(words) + .reduce((a, b) -> a + b).orElse("") // Merge all strings + .chars().mapToObj(c -> (char) c) + .collect(Collectors.groupingBy(Function.identity(), HashMap::new, Collectors.counting())) // Build a frequency map + .values().stream() + .allMatch(v -> v % words.length == 0); // Predicate logic to check frequency of each character + } +} diff --git a/Easy/Reformat Date.java b/Easy/Reformat Date.java index fdde8bc3..2230d7a6 100644 --- a/Easy/Reformat Date.java +++ b/Easy/Reformat Date.java @@ -1,16 +1,22 @@ class Solution { + private static final String[] MONTHS = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + public String reformatDate(String date) { - String[] months = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - Map monthMap = new HashMap<>(); - for (int i = 1; i <= 12; i++) { - monthMap.put(months[i - 1], (i > 9 ? "" : "0") + i); - } - String[] strs = date.split("\\s+"); - int dayEndIdx = 0; - while (dayEndIdx < strs[0].length() && Character.isDigit(strs[0].charAt(dayEndIdx))) { - dayEndIdx++; + String[] split = date.split("\\s+"); + StringBuilder sb = new StringBuilder(); + sb.append(split[2]).append("-"); + int monthIdx = getMonthIdx(split[1]); + sb.append(monthIdx > 9 ? "" : "0").append(monthIdx).append("-"); + sb.append(Character.isDigit(split[0].charAt(1)) ? split[0].substring(0, 2) : ("0" + split[0].charAt(0))); + return sb.toString(); + } + + private int getMonthIdx(String month) { + for (int i = 0; i < MONTHS.length; i++) { + if (month.equals(MONTHS[i])) { + return i + 1; + } } - String dayStr = strs[0].substring(0, dayEndIdx); - return strs[2] + "-" + monthMap.get(strs[1]) + "-" + (dayStr.length() == 2 ? dayStr : "0" + dayStr); + return -1; } } diff --git a/Easy/Reformat Phone Number.java b/Easy/Reformat Phone Number.java new file mode 100644 index 00000000..a2f9dfa6 --- /dev/null +++ b/Easy/Reformat Phone Number.java @@ -0,0 +1,29 @@ +class Solution { + public String reformatNumber(String number) { + List digits = number.chars().mapToObj(c -> (char) c).filter(Character::isDigit) + .collect(Collectors.toList()); + StringBuilder sb = new StringBuilder(); + int remainingCharacter = digits.size(); + int idx = 0; + while (remainingCharacter > 4) { + for (int i = 0; i < 3; i++) { + sb.append(digits.get(idx++)); + } + remainingCharacter -= 3; + sb.append("-"); + } + if (remainingCharacter > 3) { + for (int i = 0; i < 4; i++) { + sb.append(digits.get(idx++)); + if (i == 1) { + sb.append('-'); + } + } + } else { + for (; idx < digits.size(); idx++) { + sb.append(digits.get(idx)); + } + } + return sb.toString(); + } +} diff --git a/Easy/Relative Sort Array.java b/Easy/Relative Sort Array.java index 886b0c71..efee0153 100644 --- a/Easy/Relative Sort Array.java +++ b/Easy/Relative Sort Array.java @@ -1,32 +1,21 @@ class Solution { public int[] relativeSortArray(int[] arr1, int[] arr2) { - Map map = new HashMap<>(); - for (int i = 0; i < arr2.length; i++) { - map.put(arr2[i], i); - } - PriorityQueue pq = new PriorityQueue<>(new Comparator(){ - public int compare(Integer o1, Integer o2) { - return map.get(o1) - map.get(o2); - } - }); - List notPresent = new ArrayList<>(); + int[] frequency = new int[1001]; for (int num : arr1) { - if (map.containsKey(num)) { - pq.add(num); - } - else { - notPresent.add(num); - } + frequency[num]++; } - int[] ans = new int[arr1.length]; + int[] result = new int[arr1.length]; int idx = 0; - while (!pq.isEmpty()) { - ans[idx++] = pq.poll(); + for (int num : arr2) { + while (frequency[num]-- > 0) { + result[idx++] = num; + } } - Collections.sort(notPresent); - for (int num : notPresent) { - ans[idx++] = num; + for (int i = 0; i < 1001; i++) { + while (frequency[i]-- > 0) { + result[idx++] = i; + } } - return ans; + return result; } } diff --git a/Easy/Relative ranks.java b/Easy/Relative ranks.java index 211226ea..94e12902 100644 --- a/Easy/Relative ranks.java +++ b/Easy/Relative ranks.java @@ -1,34 +1,20 @@ -import java.util.Arrays; - -public class Solution { - public String[] findRelativeRanks(int[] nums) { - int[] nums_copy = nums.clone(); - Arrays.sort(nums); - for (int i = 0; i < nums.length / 2; i++) { - int temp = nums[i]; - nums[i] = nums[nums.length - 1 - i]; - nums[nums.length - 1 - i] = temp; - } - - String[] rank = {"Gold Medal", "Silver Medal", "Bronze Medal"}; - - String[] ans = new String[nums.length]; - for (int i=0;i orderedRanking = new PriorityQueue<>((o1, o2) -> nums[o2] - nums[o1]); + orderedRanking.addAll(IntStream.range(0, nums.length).boxed().collect(Collectors.toList())); + String[] relativeRanks = new String[nums.length]; + int currentRank = 1; + while (!orderedRanking.isEmpty()) { + int removed = orderedRanking.poll(); + if (currentRank > 3) { + relativeRanks[removed] = String.valueOf(currentRank++); + } else { + relativeRanks[removed] = ( + currentRank == 1 ? "Gold Medal" : (currentRank == 2 ? "Silver Medal" : "Bronze Medal") + ); + currentRank++; + } } - public int findIndex(int[] nums, int elem) { - for (int i=0;i stack = new Stack<>(); - char[] chars = S.toCharArray(); - for (int i = 0; i < S.length(); i++) { - if (stack.isEmpty() || chars[stack.peek()] != chars[i]) { - stack.push(i); - } - else { - chars[i] = '-'; - chars[stack.pop()] = '-'; - } + public String removeDuplicates(String s) { + Stack stack = new Stack<>(); + for (char c : s.toCharArray()) { + if (!stack.isEmpty() && stack.peek() == c) { + stack.pop(); + } else { + stack.push(c); + } + } + StringBuilder sb = new StringBuilder(); + while (!stack.isEmpty()) { + sb.append(stack.pop()); + } + return sb.reverse().toString(); } - StringBuilder sb = new StringBuilder(); - for (char c : chars) { - if (c != '-') { - sb.append(c); - } - } - return sb.toString(); - } } diff --git a/Easy/Remove Digit From Number to Maximize Result.java b/Easy/Remove Digit From Number to Maximize Result.java new file mode 100644 index 00000000..b789ea2c --- /dev/null +++ b/Easy/Remove Digit From Number to Maximize Result.java @@ -0,0 +1,14 @@ +class Solution { + public String removeDigit(String number, char digit) { + int lastOccurrence = -1; + for (int i = 0; i < number.length(); i++) { + if (number.charAt(i) == digit) { + if (i + 1 < number.length() && number.charAt(i + 1) > digit) { + return number.substring(0, i) + number.substring(i + 1); + } + lastOccurrence = i; + } + } + return number.substring(0, lastOccurrence) + number.substring(lastOccurrence + 1); + } +} diff --git a/Easy/Remove Duplicates From Sorted Lists.java b/Easy/Remove Duplicates From Sorted Lists.java index 53626725..fbd899d4 100644 --- a/Easy/Remove Duplicates From Sorted Lists.java +++ b/Easy/Remove Duplicates From Sorted Lists.java @@ -3,19 +3,19 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode deleteDuplicates(ListNode head) { ListNode curr = head; while (curr != null) { - if (curr.next != null && curr.val == curr.next.val) { + while (curr.next != null && curr.next.val == curr.val) { curr.next = curr.next.next; } - else { - curr = curr.next; - } + curr = curr.next; } return head; } diff --git a/Easy/Remove Duplicates from Sorted Array.java b/Easy/Remove Duplicates from Sorted Array.java index 7349f2f2..7c285a36 100644 --- a/Easy/Remove Duplicates from Sorted Array.java +++ b/Easy/Remove Duplicates from Sorted Array.java @@ -1,15 +1,14 @@ class Solution { public int removeDuplicates(int[] nums) { - int start = 0; - int end = 0; - int n = nums.length; - while (end < n) { - int curr = nums[end]; - while (end < n && nums[end] == curr) { - end++; + int startIdx = 0; + int endIdx = 0; + while (endIdx < nums.length) { + int currValue = nums[endIdx]; + while (endIdx < nums.length && nums[endIdx] == currValue) { + endIdx++; } - nums[start++] = curr; + nums[startIdx++] = currValue; } - return start; + return startIdx; } } diff --git a/Easy/Remove Element.java b/Easy/Remove Element.java index f879483d..c75e9bb7 100644 --- a/Easy/Remove Element.java +++ b/Easy/Remove Element.java @@ -1,14 +1,11 @@ class Solution { public int removeElement(int[] nums, int val) { - int start = 0; - int end = 0; - int n = nums.length; - while (end < n) { - if (nums[end] != val) { - nums[start++] = nums[end]; + int idx = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] != val) { + nums[idx++] = nums[i]; } - end++; } - return start; + return idx; } } diff --git a/Easy/Remove Letter To Equalize Frequency.java b/Easy/Remove Letter To Equalize Frequency.java new file mode 100644 index 00000000..05c950c2 --- /dev/null +++ b/Easy/Remove Letter To Equalize Frequency.java @@ -0,0 +1,27 @@ +class Solution { + public boolean equalFrequency(String word) { + int[] frequency = new int[26]; + int maxFrequency = 0; + for (char c : word.toCharArray()) { + frequency[c - 'a']++; + maxFrequency = Math.max(maxFrequency, frequency[c - 'a']); + } + int maxCount = 0; + int maxMinusOneCount = 0; + for (int i = 0; i < 26; i++) { + if (frequency[i] == 0) { + continue; + } + if (frequency[i] == maxFrequency) { + maxCount++; + } + if (frequency[i] == maxFrequency - 1) { + maxMinusOneCount++; + } + if (frequency[i] < maxFrequency - 1) { + return false; + } + } + return maxMinusOneCount == 1 || maxCount == 1 || (maxMinusOneCount == 0 && maxFrequency == 1); + } +} diff --git a/Easy/Remove Linked List Elements.java b/Easy/Remove Linked List Elements.java index 9bc15504..41684468 100644 --- a/Easy/Remove Linked List Elements.java +++ b/Easy/Remove Linked List Elements.java @@ -10,16 +10,16 @@ */ class Solution { public ListNode removeElements(ListNode head, int val) { - while (head != null && head.val == val) { - head = head.next; + ListNode newHead = null; + ListNode curr = head; + while (curr != null && curr.val == val) { + curr = curr.next; } - ListNode newHead = head; - ListNode curr = newHead; + newHead = curr; while (curr != null && curr.next != null) { if (curr.next.val == val) { curr.next = curr.next.next; - } - else { + } else { curr = curr.next; } } diff --git a/Easy/Remove One Element to Make the Array Strictly Increasing.java b/Easy/Remove One Element to Make the Array Strictly Increasing.java new file mode 100644 index 00000000..74c4bf1d --- /dev/null +++ b/Easy/Remove One Element to Make the Array Strictly Increasing.java @@ -0,0 +1,17 @@ +class Solution { + public boolean canBeIncreasing(int[] nums) { + boolean removed = false; + for (int i = 1; i < nums.length; i++) { + if (nums[i] <= nums[i - 1]) { + if (removed) { + return false; + } + removed = true; + if (i > 1 && nums[i] <= nums[i - 2]) { + nums[i] = nums[i - 1]; + } + } + } + return true; + } +} diff --git a/Easy/Remove Palindromic Subsequences.java b/Easy/Remove Palindromic Subsequences.java new file mode 100644 index 00000000..e4e10845 --- /dev/null +++ b/Easy/Remove Palindromic Subsequences.java @@ -0,0 +1,17 @@ +class Solution { + public int removePalindromeSub(String s) { + if (s.length() == 0) { + return 0; + } + int start = 0; + int end = s.length() - 1; + while (start <= end) { + if (s.charAt(start) != s.charAt(end)) { + return 2; + } + start++; + end--; + } + return 1; + } +} diff --git a/Easy/Remove Trailing Zeros From a String.java b/Easy/Remove Trailing Zeros From a String.java new file mode 100644 index 00000000..996c079e --- /dev/null +++ b/Easy/Remove Trailing Zeros From a String.java @@ -0,0 +1,9 @@ +class Solution { + public String removeTrailingZeros(String num) { + int idx = num.length() - 1; + while (idx >= 0 && num.charAt(idx) == '0') { + idx--; + } + return num.substring(0, idx + 1); + } +} diff --git a/Easy/Remove Vowels from a String.java b/Easy/Remove Vowels from a String.java index f389ac47..d5c24c1b 100644 --- a/Easy/Remove Vowels from a String.java +++ b/Easy/Remove Vowels from a String.java @@ -1,14 +1,11 @@ class Solution { - public String removeVowels(String S) { - StringBuilder sb = new StringBuilder(); - Set set = new HashSet<>(Arrays.asList('a', 'e', 'i', 'o', 'u')); - - for (char c : S.toCharArray()) { - if (!set.contains(c)) { - sb.append(c); - } - } - - return sb.toString(); - } + public String removeVowels(String s) { + return s.chars() + .mapToObj(c -> (char) c) + .filter(c -> "aeiou".indexOf(c) == -1) + .collect(Collector.of(StringBuilder::new, + StringBuilder::append, + StringBuilder::append, + StringBuilder::toString)); + } } diff --git a/Easy/Reorder Data in Log Files.java b/Easy/Reorder Data in Log Files.java deleted file mode 100644 index df293c3d..00000000 --- a/Easy/Reorder Data in Log Files.java +++ /dev/null @@ -1,35 +0,0 @@ -class Solution { - public String[] reorderLogFiles(String[] logs) { - List letterLogs = new ArrayList<>(); - List digitLogs = new ArrayList<>(); - for (String log : logs) { - String[] strs = log.split("\\s+"); - if (Character.isDigit(strs[1].charAt(0))) { - digitLogs.add(log); - } - else { - letterLogs.add(log); - } - } - Collections.sort(letterLogs, new Comparator(){ - public int compare(String s1, String s2) { - String key1 = s1.substring(s1.indexOf(' ') + 1); - String key2 = s2.substring(s2.indexOf(' ') + 1); - int c = key1.compareTo(key2); - if (c != 0) { - return c; - } - return s1.substring(0, s1.indexOf(' ')).compareTo(s2.substring(0, s2.indexOf(' '))); - } - }); - String[] ans = new String[logs.length]; - int idx = 0; - for (String log : letterLogs) { - ans[idx++] = log; - } - for (String log : digitLogs) { - ans[idx++] = log; - } - return ans; - } -} diff --git a/Easy/Repeated Substring Pattern.java b/Easy/Repeated Substring Pattern.java index 79ea250c..fc817f7e 100644 --- a/Easy/Repeated Substring Pattern.java +++ b/Easy/Repeated Substring Pattern.java @@ -1,19 +1,16 @@ class Solution { - public boolean repeatedSubstringPattern(String s) { - int n = s.length(); - for (int i = n / 2; i >= 1; i--) { - if (n % i == 0) { - int count = n / i; - StringBuilder sb = new StringBuilder(); - String sub = s.substring(0, i); - while (count-- > 0) { - sb.append(sub); + public boolean repeatedSubstringPattern(String s) { + int n = s.length(); + for (int i = n / 2; i > 0; i--) { + if (n % i == 0) { + int count = n / i; + String substring = s.substring(0, i); + String repeatedString = substring.repeat(count); + if (repeatedString.equals(s)) { + return true; + } + } } - if (sb.toString().equals(s)) { - return true; - } - } + return false; } - return false; - } } diff --git a/Easy/Replace All ?'s to Avoid Consecutive Repeating Characters.java b/Easy/Replace All ?'s to Avoid Consecutive Repeating Characters.java new file mode 100644 index 00000000..57c5a54c --- /dev/null +++ b/Easy/Replace All ?'s to Avoid Consecutive Repeating Characters.java @@ -0,0 +1,22 @@ +class Solution { + private final char[] ALL_CHARACTERS = "abcdefghijklmnopqrstuvwxyz".toCharArray(); + public String modifyString(String s) { + char[] charArray = s.toCharArray(); + for (int idx = 0; idx < charArray.length; idx++) { + if (charArray[idx] == '?') { + charArray[idx] = getNonRepeatingChar(charArray, idx); + } + } + return String.valueOf(charArray); + } + + private char getNonRepeatingChar(char[] charArray, int idx) { + for (char c : ALL_CHARACTERS) { + if ((idx == 0 || charArray[idx - 1] == '?' || charArray[idx - 1] != c) && + (idx == charArray.length - 1 || charArray[idx + 1] == '?' || charArray[idx + 1] != c)) { + return c; + } + } + return charArray[idx]; + } +} diff --git a/Easy/Replace All Digits with Characters.java b/Easy/Replace All Digits with Characters.java new file mode 100644 index 00000000..92047d4e --- /dev/null +++ b/Easy/Replace All Digits with Characters.java @@ -0,0 +1,11 @@ +class Solution { + public String replaceDigits(String s) { + StringBuilder sb = new StringBuilder(); + int n = s.length(); + for (int i = 1; i < n; i += 2) { + char c = s.charAt(i - 1); + sb.append(c).append((char) (((int) c) + Character.getNumericValue(s.charAt(i)))); + } + return n % 2 != 0 ? sb.append(s.charAt(n - 1)).toString() : sb.toString(); + } +} diff --git a/Easy/Reshape the matrix.java b/Easy/Reshape the matrix.java index 1093a616..ca61f4e4 100644 --- a/Easy/Reshape the matrix.java +++ b/Easy/Reshape the matrix.java @@ -1,31 +1,22 @@ class Solution { - public int[][] matrixReshape(int[][] nums, int r, int c) { - int numOfElem = nums.length*nums[0].length; - if (numOfElem != r*c) { - return nums; + public int[][] matrixReshape(int[][] mat, int r, int c) { + int m = mat.length; + int n = mat[0].length; + if (m * n != r * c) { + return mat; } - - int[] expandedArray = new int[numOfElem]; - int k = 0; - - for (int i=0;i>= 1; } - return res; + return result; } } diff --git a/Easy/Reverse Degree of a String.java b/Easy/Reverse Degree of a String.java new file mode 100644 index 00000000..db8f4e91 --- /dev/null +++ b/Easy/Reverse Degree of a String.java @@ -0,0 +1,9 @@ +class Solution { + public int reverseDegree(String s) { + int result = 0; + for (int i = 0; i < s.length(); i++) { + result += (i + 1) * (26 - (s.charAt(i) - 'a')); + } + return result; + } +} diff --git a/Easy/Reverse Integer.java b/Easy/Reverse Integer.java deleted file mode 100644 index 330bbff2..00000000 --- a/Easy/Reverse Integer.java +++ /dev/null @@ -1,17 +0,0 @@ -public class Solution { - public int reverse(int x) { - int result = 0; - - while (x != 0) - { - int tail = x % 10; - int newResult = result * 10 + tail; - if ((newResult - tail) / 10 != result) - { return 0; } - result = newResult; - x = x / 10; - } - - return result; - } -} \ No newline at end of file diff --git a/Easy/Reverse Linked List.java b/Easy/Reverse Linked List.java index e729c133..61877d65 100644 --- a/Easy/Reverse Linked List.java +++ b/Easy/Reverse Linked List.java @@ -3,22 +3,22 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { - public ListNode reverseList(ListNode head) { - ListNode prev = null; - ListNode curr = head; - ListNode next = null; - - while (curr != null) { - next = curr.next; - curr.next = prev; - prev = curr; - curr = next; - } - - return prev; + public ListNode reverseList(ListNode head) { + ListNode prev = null; + ListNode next = null; + ListNode curr = head; + while (curr != null) { + next = curr.next; + curr.next = prev; + prev = curr; + curr = next; } + return prev; + } } diff --git a/Easy/Reverse Only Letters.java b/Easy/Reverse Only Letters.java index 95aa10f5..acdd5168 100644 --- a/Easy/Reverse Only Letters.java +++ b/Easy/Reverse Only Letters.java @@ -1,23 +1,21 @@ class Solution { - public String reverseOnlyLetters(String S) { + public String reverseOnlyLetters(String s) { int start = 0; - int end = S.length() - 1; - char[] chars = S.toCharArray(); + int end = s.length() - 1; + char[] letters = s.toCharArray(); while (start <= end) { - while (start <= end && !Character.isLetter(chars[start])) { + while (start <= end && !Character.isLetter(s.charAt(start))) { start++; } - while (end >= start && !Character.isLetter(chars[end])) { + while (end >= start && !Character.isLetter(s.charAt(end))) { end--; } if (start <= end) { - char temp = chars[start]; - chars[start] = chars[end]; - chars[end] = temp; + char temp = letters[start]; + letters[start++] = letters[end]; + letters[end--] = temp; } - start++; - end--; } - return String.valueOf(chars); + return String.valueOf(letters); } } diff --git a/Easy/Reverse Prefix of Word.java b/Easy/Reverse Prefix of Word.java new file mode 100644 index 00000000..3799c707 --- /dev/null +++ b/Easy/Reverse Prefix of Word.java @@ -0,0 +1,10 @@ +class Solution { + public String reversePrefix(String word, char ch) { + for (int i = 0; i < word.length(); i++) { + if (word.charAt(i) == ch) { + return new StringBuilder().append(word.substring(0, i + 1)).reverse().toString() + word.substring(i + 1); + } + } + return word; + } +} diff --git a/Easy/Reverse String II.java b/Easy/Reverse String II.java index a2e13d9a..168f553d 100644 --- a/Easy/Reverse String II.java +++ b/Easy/Reverse String II.java @@ -1,26 +1,15 @@ class Solution { public String reverseStr(String s, int k) { + boolean reverse = true; StringBuilder sb = new StringBuilder(); - boolean current = true; - int idx = 0; - int n = s.length(); - while (idx < n) { - int endIdx = Math.min(idx + k - 1, n - 1); - if (current) { - int end = idx; - int start = endIdx; - for (int i = start; i >= end; i--) { - sb.append(s.charAt(i)); - } - idx = endIdx + 1; + for (int i = 0; i < s.length(); i += k) { + String substring = s.substring(i, Math.min(i + k, s.length())); + if (reverse) { + sb.append(new StringBuilder().append(substring).reverse().toString()); + } else { + sb.append(substring); } - else { - while (idx <= endIdx) { - sb.append(s.charAt(idx++)); - } - } - current = !current; - System.out.println(idx); + reverse = !reverse; } return sb.toString(); } diff --git a/Easy/Reverse Vowels of a String.java b/Easy/Reverse Vowels of a String.java index c1ea0294..ea10d13c 100644 --- a/Easy/Reverse Vowels of a String.java +++ b/Easy/Reverse Vowels of a String.java @@ -1,24 +1,24 @@ class Solution { - public String reverseVowels(String s) { - int left = 0; - int right = s.length() - 1; - String vowels = "aeiouAEIOU"; - char[] chars = s.toCharArray(); - while (left < right) { - int vowelIndexLeft = vowels.indexOf(chars[left]); - int vowelIndexRight = vowels.indexOf(chars[right]); - if (vowelIndexLeft != -1 && vowelIndexRight != -1) { - char temp = chars[left]; - chars[left++] = chars[right]; - chars[right--] = temp; - } - else if (vowelIndexRight == -1) { - right--; - } - else { - left++; - } + + private static final Set VOWELS = Set.of('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'); + + public String reverseVowels(String s) { + int left = 0; + int right = s.length() - 1; + char[] chars = s.toCharArray(); + while (left <= right) { + if (VOWELS.contains(chars[left]) && VOWELS.contains(chars[right])) { + char temp = chars[left]; + chars[left] = chars[right]; + chars[right] = temp; + left++; + right--; + } else if (!VOWELS.contains(chars[left])) { + left++; + } else if (!VOWELS.contains(chars[right])) { + right--; + } + } + return String.valueOf(chars); } - return String.valueOf(chars); - } } diff --git a/Easy/Reverse words in a String III.java b/Easy/Reverse words in a String III.java index e50dd770..c6c46160 100644 --- a/Easy/Reverse words in a String III.java +++ b/Easy/Reverse words in a String III.java @@ -1,23 +1,30 @@ class Solution { - public String reverseWords(String s) { - int idx = 0; - int n = s.length(); - StringBuilder sb = new StringBuilder(); - int start = 0; - while (idx < n) { - while (idx < n && s.charAt(idx) != ' ') { - idx++; - } - int curr = idx - 1; - while (curr >= start) { - sb.append(s.charAt(curr--)); - } - if (idx != n) { - sb.append(" "); - } - idx++; - start = idx; + public String reverseWords(String s) { + int start = 0; + int end = 0; + char[] chars = s.toCharArray(); + while (end < s.length()) { + if (chars[end] == ' ') { + if (start < end - 1) { + reverse(chars, start, end - 1); + } + end++; + start = end; + } else { + end++; + } + } + if (start < end) { + reverse(chars, start, end - 1); + } + return String.valueOf(chars); + } + + private void reverse(char[] chars, int start, int end) { + while (start < end) { + char temp = chars[start]; + chars[start++] = chars[end]; + chars[end--] = temp; + } } - return sb.toString(); - } } diff --git a/Easy/Richest Customer Wealth.java b/Easy/Richest Customer Wealth.java new file mode 100644 index 00000000..e7ff34dc --- /dev/null +++ b/Easy/Richest Customer Wealth.java @@ -0,0 +1,8 @@ +class Solution { + public int maximumWealth(int[][] accounts) { + return Arrays.stream(accounts) + .map(e -> Arrays.stream(e).sum()) + .max(Integer::compareTo) + .orElse(0); + } +} diff --git a/Easy/Rings and Rods.java b/Easy/Rings and Rods.java new file mode 100644 index 00000000..fd98b60a --- /dev/null +++ b/Easy/Rings and Rods.java @@ -0,0 +1,11 @@ +class Solution { + public int countPoints(String rings) { + Map> map = new HashMap<>(); + for (int i = 0; i < rings.length(); i += 2) { + char ring = rings.charAt(i); + int rod = Character.getNumericValue(rings.charAt(i + 1)); + map.computeIfAbsent(rod, k -> new HashSet()).add(ring); + } + return (int) map.values().stream().filter(v -> v.size() == 3).count(); + } +} diff --git a/Easy/Roman to Integer.java b/Easy/Roman to Integer.java index 7b269b0b..c0c047ee 100644 --- a/Easy/Roman to Integer.java +++ b/Easy/Roman to Integer.java @@ -1,25 +1,23 @@ class Solution { + public int romanToInt(String s) { - String[] keys = {"I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"}; - int[] values = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000}; + String[] strings = {"I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"}; + int[] value = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000}; Map map = new HashMap<>(); - for (int i = 0; i < keys.length; i++) { - map.put(keys[i], values[i]); - } - int val = 0; + for (int i = 0; i < strings.length; i++) { + map.put(strings[i], value[i]); + } int idx = 0; - int n = s.length(); - while (idx < n) { - char c = s.charAt(idx); - if (idx + 1 < n && map.containsKey(s.substring(idx, idx + 2))) { - val += map.get(s.substring(idx, idx + 2)); + int num = 0; + while (idx < s.length()) { + if (idx + 1 < s.length() && map.containsKey(s.substring(idx, idx + 2))) { + num += map.get(s.substring(idx, idx + 2)); idx += 2; - } - else { - val += map.get(String.valueOf(c)); + } else { + num += map.get(s.substring(idx, idx + 1)); idx++; } } - return val; + return num; } } diff --git a/Easy/Root Equals Sum of Children.java b/Easy/Root Equals Sum of Children.java new file mode 100644 index 00000000..a354dc1a --- /dev/null +++ b/Easy/Root Equals Sum of Children.java @@ -0,0 +1,20 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public boolean checkTree(TreeNode root) { + return root.val == (root.left.val + root.right.val); + } +} diff --git a/Easy/Rotate Array.java b/Easy/Rotate Array.java deleted file mode 100644 index 80e108e3..00000000 --- a/Easy/Rotate Array.java +++ /dev/null @@ -1,12 +0,0 @@ -public class Solution { - public void rotate(int[] nums, int k) { - int[] n = new int[nums.length]; - for (int i=0;i maxOnes) { + maxOnes = oneCount; + maxOnesRow = i; + } + } + return new int[]{maxOnesRow, maxOnes}; + } +} diff --git a/Easy/Running Sum of 1d Array.java b/Easy/Running Sum of 1d Array.java index 75f635ca..bc5f422a 100644 --- a/Easy/Running Sum of 1d Array.java +++ b/Easy/Running Sum of 1d Array.java @@ -1,11 +1,10 @@ class Solution { public int[] runningSum(int[] nums) { - int[] ans = new int[nums.length]; int sum = 0; for (int i = 0; i < nums.length; i++) { sum += nums[i]; - ans[i] = sum; + nums[i] = sum; } - return ans; + return nums; } } diff --git a/Easy/Score of a String.java b/Easy/Score of a String.java new file mode 100644 index 00000000..fafcca05 --- /dev/null +++ b/Easy/Score of a String.java @@ -0,0 +1,9 @@ +class Solution { + public int scoreOfString(String s) { + int score = 0; + for (int i = 1; i < s.length(); i++) { + score += Math.abs(s.charAt(i) - s.charAt(i - 1)); + } + return score; + } +} diff --git a/Easy/Search Insert Position.java b/Easy/Search Insert Position.java index b6187b17..3e2f930c 100644 --- a/Easy/Search Insert Position.java +++ b/Easy/Search Insert Position.java @@ -1,19 +1,17 @@ class Solution { public int searchInsert(int[] nums, int target) { - int low = 0; - int high = nums.length - 1; - while (low <= high) { - int mid = (low + high) / 2; + int left = 0; + int right = nums.length - 1; + while (left <= right) { + int mid = (left + right) / 2; if (nums[mid] == target) { return mid; - } - else if (nums[mid] > target) { - high = mid - 1; - } - else { - low = mid + 1; + } else if (nums[mid] > target) { + right = mid - 1; + } else { + left = mid + 1; } } - return low; + return left; } } diff --git a/Easy/Search in a Binary Search Tree.java b/Easy/Search in a Binary Search Tree.java index caed08fe..e3c00460 100644 --- a/Easy/Search in a Binary Search Tree.java +++ b/Easy/Search in a Binary Search Tree.java @@ -14,18 +14,21 @@ * } */ class Solution { - public TreeNode searchBST(TreeNode root, int val) { - if (root == null) { - return null; + public TreeNode searchBST(TreeNode root, int val) { + Queue queue = new LinkedList<>(); + queue.add(root); + while (!queue.isEmpty()) { + TreeNode removed = queue.remove(); + if (removed.val == val) { + return removed; + } + if (removed.val > val && removed.left != null) { + queue.add(removed.left); + } + if (removed.val < val && removed.right != null) { + queue.add(removed.right); + } + } + return null; } - if (root.val == val) { - return root; - } - else if (root.val > val) { - return searchBST(root.left, val); - } - else { - return searchBST(root.right, val); - } - } } diff --git a/Easy/Second Largest Digit in a String.java b/Easy/Second Largest Digit in a String.java new file mode 100644 index 00000000..c4930136 --- /dev/null +++ b/Easy/Second Largest Digit in a String.java @@ -0,0 +1,20 @@ +class Solution { + public int secondHighest(String s) { + int maximumNum = -1; + int secondMaximumNum = -1; + for (char c : s.toCharArray()) { + if (Character.isDigit(c)) { + int num = Character.getNumericValue(c); + if (maximumNum < num) { + if (secondMaximumNum < maximumNum) { + secondMaximumNum = maximumNum; + } + maximumNum = num; + } else if (secondMaximumNum < num && num < maximumNum) { + secondMaximumNum = num; + } + } + } + return secondMaximumNum; + } +} diff --git a/Easy/Second Minimum Node in a binary tree.java b/Easy/Second Minimum Node in a binary tree.java index 2a3434b1..8ddeb335 100644 --- a/Easy/Second Minimum Node in a binary tree.java +++ b/Easy/Second Minimum Node in a binary tree.java @@ -13,26 +13,22 @@ * } * } */ -class Solution { - Integer minimum; - long secondMinimum; +class Solution { public int findSecondMinimumValue(TreeNode root) { - minimum = root.val; - secondMinimum = Long.MAX_VALUE; - helper(root); - return secondMinimum == Long.MAX_VALUE ? -1 : (int) secondMinimum; + long[] topTwo = {root.val, Long.MAX_VALUE}; + helper(root, topTwo); + return topTwo[1] == Long.MAX_VALUE ? -1 : (int) topTwo[1]; } - private void helper(TreeNode root) { + private void helper(TreeNode root, long[] topTwo) { if (root == null) { return; } - if (minimum < root.val && root.val < secondMinimum) { - secondMinimum = root.val; - } - else if (root.val == minimum) { - helper(root.left); - helper(root.right); + if (topTwo[0] < root.val && root.val < topTwo[1]) { + topTwo[1] = root.val; + } else { + helper(root.left, topTwo); + helper(root.right, topTwo); } } } diff --git a/Easy/Sentence Similarity.java b/Easy/Sentence Similarity.java index 7e779bfe..38f62e43 100644 --- a/Easy/Sentence Similarity.java +++ b/Easy/Sentence Similarity.java @@ -1,21 +1,22 @@ class Solution { - public boolean areSentencesSimilar(String[] words1, String[] words2, List> pairs) { - if (words1.length != words2.length) { + public boolean areSentencesSimilar( + String[] sentence1, String[] sentence2, List> similarPairs) { + if (sentence1.length != sentence2.length) { return false; } - Set set = new HashSet<>(); - for (List pair : pairs) { - String word1 = pair.get(0); - String word2 = pair.get(1); - set.add(word1 + "|" + word2); + Map> similarWords = new HashMap<>(); + for (List pair : similarPairs) { + similarWords.computeIfAbsent(pair.get(0), k -> new HashSet<>()).add(pair.get(1)); + similarWords.computeIfAbsent(pair.get(1), k -> new HashSet<>()).add(pair.get(0)); } - for (int i = 0; i < words1.length; i++) { - String word1 = words1[i]; - String word2 = words2[i]; - if (!(word1.equals(word2) || set.contains(word1 + "|" + word2) || set.contains(word2 + "|" + word1))) { - return false; + for (int i = 0; i < sentence1.length; i++) { + if (sentence1[i].equals(sentence2[i]) + || similarWords.getOrDefault(sentence1[i], new HashSet<>()).contains(sentence2[i]) + || similarWords.getOrDefault(sentence2[i], new HashSet<>()).contains(sentence1[1])) { + continue; } + return false; } - return true; + return sentence1.length != sentence2.length; } } diff --git a/Easy/Separate the Digits in an Array.java b/Easy/Separate the Digits in an Array.java new file mode 100644 index 00000000..9bd6878f --- /dev/null +++ b/Easy/Separate the Digits in an Array.java @@ -0,0 +1,19 @@ +class Solution { + public int[] separateDigits(int[] nums) { + List result = new ArrayList<>(); + for (int num : nums) { + int startIdx = result.size(); + while (num > 0) { + result.add(num % 10); + num /= 10; + } + int endIdx = result.size() - 1; + while (startIdx < endIdx) { + int temp = result.get(startIdx); + result.set(startIdx++, result.get(endIdx)); + result.set(endIdx--, temp); + } + } + return result.stream().mapToInt(Integer::intValue).toArray(); + } +} diff --git a/Easy/Set Mismatch.java b/Easy/Set Mismatch.java index 49ba13f1..eac82238 100644 --- a/Easy/Set Mismatch.java +++ b/Easy/Set Mismatch.java @@ -1,26 +1,19 @@ class Solution { public int[] findErrorNums(int[] nums) { - int[] ans = {-1,1}; - Map map = new HashMap<>(); - - for(int i=0;i set = new HashSet<>(); + for (int i = 1; i <= n; i++) { + if (!set.add(nums[i - 1])) { + result[0] = nums[i - 1]; } } - - for (int i=1;i<=nums.length;i++) { - if (!map.containsKey(i)) { - ans[1] = i; - } - if (map.containsKey(i) && map.get(i) == 2) { - ans[0] = i; + for (int i = 1; i <= n; i++) { + if (!set.contains(i)) { + result[1] = i; + break; } } - - return ans; + return result; } } diff --git a/Easy/Shortest Completing Word.java b/Easy/Shortest Completing Word.java index 1be5e2f8..5e9c9cb3 100644 --- a/Easy/Shortest Completing Word.java +++ b/Easy/Shortest Completing Word.java @@ -1,33 +1,34 @@ class Solution { public String shortestCompletingWord(String licensePlate, String[] words) { - Map licenseMap = new HashMap<>(); - for (Character c : licensePlate.toCharArray()) { - if (Character.isLetter(c)) { - licenseMap.put(Character.toLowerCase(c), licenseMap.getOrDefault(Character.toLowerCase(c), 0) + 1); - } - } - int minLength = Integer.MAX_VALUE; - int minLengthIdx = -1; + int shortestWordIdx = -1; + Map licensePlateFrequency = getFrequencyMap(licensePlate); for (int i = 0; i < words.length; i++) { - Map copyMap = new HashMap<>(licenseMap); - boolean found = false; - for (Character c : words[i].toCharArray()) { - if (copyMap.containsKey(Character.toLowerCase(c))) { - copyMap.put(Character.toLowerCase(c), copyMap.get(Character.toLowerCase(c)) - 1); - if (copyMap.get(Character.toLowerCase(c)) == 0) { - copyMap.remove(Character.toLowerCase(c)); - } - } - if (copyMap.size() == 0) { - found = true; - break; + if (canComplete(licensePlateFrequency, words[i])) { + if (shortestWordIdx == -1 || words[i].length() < words[shortestWordIdx].length()) { + shortestWordIdx = i; } } - if (found && words[i].length() < minLength) { - minLength = words[i].length(); - minLengthIdx = i; + } + return words[shortestWordIdx]; + } + + private boolean canComplete(Map licensePlateFrequency, String word) { + Map wordFrequency = getFrequencyMap(word); + for (Character key : licensePlateFrequency.keySet()) { + if (wordFrequency.getOrDefault(key, 0) < licensePlateFrequency.get(key)) { + return false; + } + } + return true; + } + + private Map getFrequencyMap(String s) { + Map map = new HashMap<>(); + for (char c : s.toCharArray()) { + if (Character.isLetter(c)) { + map.put(Character.toLowerCase(c), map.getOrDefault(Character.toLowerCase(c), 0) + 1); } } - return words[minLengthIdx]; + return map; } } diff --git a/Easy/Shortest Distance to Target String in a Circular Array.java b/Easy/Shortest Distance to Target String in a Circular Array.java new file mode 100644 index 00000000..9280c7b9 --- /dev/null +++ b/Easy/Shortest Distance to Target String in a Circular Array.java @@ -0,0 +1,24 @@ +class Solution { + public int closetTarget(String[] words, String target, int startIndex) { + int firstIdx = -1; + int lastIdx = -1; + int n = words.length; + int minDistance = Integer.MAX_VALUE; + for (int i = 0; i < n; i++) { + if (words[i].equals(target)) { + if (firstIdx == -1) { + firstIdx = i; + } + lastIdx = i; + minDistance = Math.min(minDistance, Math.abs(i - startIndex)); + } + } + if (minDistance == Integer.MAX_VALUE) { + return -1; + } + return Math.min(minDistance, Math.min( + n - startIndex + firstIdx, // Reach first instance by circulating from end of array + startIndex + n - lastIdx // Reach last instance by circulating from start of array + )); + } +} diff --git a/Easy/Shortest Subarray With OR at Least K I.java b/Easy/Shortest Subarray With OR at Least K I.java new file mode 100644 index 00000000..0032852b --- /dev/null +++ b/Easy/Shortest Subarray With OR at Least K I.java @@ -0,0 +1,17 @@ +class Solution { + public int minimumSubarrayLength(int[] nums, int k) { + int n = nums.length; + int result = Integer.MAX_VALUE; + for (int i = 0; i < n; i++) { + int curr = 0; + for (int j = i; j < n; j++) { + curr |= nums[j]; + if (curr >= k) { + result = Math.min(result, j - i + 1); + break; + } + } + } + return result == Integer.MAX_VALUE ? -1 : result; + } +} diff --git a/Easy/Shortest Unsorted Continuous Subarray.java b/Easy/Shortest Unsorted Continuous Subarray.java deleted file mode 100644 index 2757ecbd..00000000 --- a/Easy/Shortest Unsorted Continuous Subarray.java +++ /dev/null @@ -1,33 +0,0 @@ -class Solution { - public int findUnsortedSubarray(int[] nums) { - - int[] copy = new int[nums.length]; - for (int i=0;i 0 ? 0 : 1; + } + return negCount % 2 == 0 ? 1 : -1; + } +} diff --git a/Easy/Similar RGB Color.java b/Easy/Similar RGB Color.java new file mode 100644 index 00000000..968464dc --- /dev/null +++ b/Easy/Similar RGB Color.java @@ -0,0 +1,16 @@ +class Solution { + public String similarRGB(String color) { + StringBuilder simlarColor = new StringBuilder(); + simlarColor.append("#"); + for (int i = 1; i < 6; i += 2) { + simlarColor.append(findClosestColor(color.substring(i, i + 2))); + } + return simlarColor.toString(); + } + + private String findClosestColor(String section) { + int num = Integer.parseInt(section, 16); + int roundedValue = Math.round((float) num / 17); + return Integer.toHexString(roundedValue).repeat(2); + } +} diff --git a/Easy/Single Number.java b/Easy/Single Number.java index 94568349..9c1601e9 100644 --- a/Easy/Single Number.java +++ b/Easy/Single Number.java @@ -1,24 +1,9 @@ -public class Solution { - public int singleNumber(int[] nums) { - if (nums.length == 1) return nums[0]; - Arrays.sort(nums); - if (nums[0] != nums[1]) { - return nums[0]; - } - boolean twice = true; - for (int i=0;i map = new HashMap<>(); - int pos = 0; - for (char c : keyboard.toCharArray()) { - map.put(c, pos++); + public int calculateTime(String keyboard, String word) { + Map map = new HashMap<>(); + for (int i = 0; i < 26; i++) { + map.put(keyboard.charAt(i), i); + } + int position = 0; + int time = 0; + for (char c : word.toCharArray()) { + time += Math.abs(position - map.get(c)); + position = map.get(c); + } + return time; } - int total = 0; - int currPos = 0; - for (char c : word.toCharArray()) { - total += Math.abs(currPos - map.get(c)); - currPos = map.get(c); - } - return total; - } } diff --git a/Easy/Slowest Key.java b/Easy/Slowest Key.java new file mode 100644 index 00000000..e1c7f29f --- /dev/null +++ b/Easy/Slowest Key.java @@ -0,0 +1,17 @@ +class Solution { + public char slowestKey(int[] releaseTimes, String keysPressed) { + int maxReleaseTime = 0; + int maxReleaseTimeIdx = 0; + for (int i = 0; i < releaseTimes.length; i++) { + int idx = keysPressed.charAt(i) - 'a'; + int currReleaseTime = i == 0 ? releaseTimes[i] : (releaseTimes[i] - releaseTimes[i - 1]); + if (currReleaseTime > maxReleaseTime) { + maxReleaseTimeIdx = idx; + maxReleaseTime = currReleaseTime; + } else if (maxReleaseTime == currReleaseTime && maxReleaseTimeIdx < idx) { + maxReleaseTimeIdx = idx; + } + } + return ((char) ('a' + maxReleaseTimeIdx)); + } +} diff --git a/Easy/Smallest Even Multiple.java b/Easy/Smallest Even Multiple.java new file mode 100644 index 00000000..24964eca --- /dev/null +++ b/Easy/Smallest Even Multiple.java @@ -0,0 +1,5 @@ +class Solution { + public int smallestEvenMultiple(int n) { + return n % 2 == 0 ? n : 2 * n; + } +} diff --git a/Easy/Smallest Index With Equal Value.java b/Easy/Smallest Index With Equal Value.java new file mode 100644 index 00000000..1c6d2ea3 --- /dev/null +++ b/Easy/Smallest Index With Equal Value.java @@ -0,0 +1,5 @@ +class Solution { + public int smallestEqual(int[] nums) { + return IntStream.range(0, nums.length).filter(i -> i % 10 == nums[i]).findFirst().orElse(-1); + } +} diff --git a/Easy/Smallest Range I.java b/Easy/Smallest Range I.java new file mode 100644 index 00000000..8ba8f821 --- /dev/null +++ b/Easy/Smallest Range I.java @@ -0,0 +1,11 @@ +class Solution { + public int smallestRangeI(int[] A, int K) { + int maximum = A[0]; + int minimum = A[0]; + for (int num : A) { + maximum = Math.max(num, maximum); + minimum = Math.min(num, minimum); + } + return Math.max(0, maximum - minimum - 2 * K); + } +} diff --git a/Easy/Snake in Matrix.java b/Easy/Snake in Matrix.java new file mode 100644 index 00000000..5dce2568 --- /dev/null +++ b/Easy/Snake in Matrix.java @@ -0,0 +1,22 @@ +class Solution { + + private static final Map COMMAND_TO_DIRECTION = Map.of( + "UP", new int[]{-1, 0}, + "DOWN", new int[]{1, 0}, + "LEFT", new int[]{0, -1}, + "RIGHT", new int[]{0, 1} + ); + + public int finalPositionOfSnake(int n, List commands) { + int position = 0; + int x = 0; + int y = 0; + for (String command : commands) { + int[] change = COMMAND_TO_DIRECTION.get(command); + x += change[0]; + y += change[1]; + position = x * n + y; + } + return position; + } +} diff --git a/Easy/Sort Array By Parity.java b/Easy/Sort Array By Parity.java index c74dcae0..0b54ae53 100644 --- a/Easy/Sort Array By Parity.java +++ b/Easy/Sort Array By Parity.java @@ -1,17 +1,16 @@ class Solution { - public int[] sortArrayByParity(int[] A) { - int evenIdx = 0; - int oddIdx = A.length - 1; - while (evenIdx < oddIdx) { - if (A[evenIdx] % 2 == 0) { - evenIdx++; - } - else { - int temp = A[evenIdx]; - A[evenIdx] = A[oddIdx]; - A[oddIdx--] = temp; - } + public int[] sortArrayByParity(int[] nums) { + int start = 0; + int end = 0; + int n = nums.length; + while (end < n) { + if (nums[end] % 2 == 0) { + int temp = nums[start]; + nums[start++] = nums[end]; + nums[end] = temp; + } + end++; + } + return nums; } - return A; - } } diff --git a/Easy/Sort Array by Increasing Frequency.java b/Easy/Sort Array by Increasing Frequency.java new file mode 100644 index 00000000..0fa7b374 --- /dev/null +++ b/Easy/Sort Array by Increasing Frequency.java @@ -0,0 +1,24 @@ +class Solution { + public int[] frequencySort(int[] nums) { + Map map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + PriorityQueue pq = new PriorityQueue<>((o1, o2) -> { + int c = map.get(o1).compareTo(map.get(o2)); + if (c != 0) { + return c; + } + return o2.compareTo(o1); + }); + pq.addAll(map.keySet()); + int idx = 0; + while (!pq.isEmpty()) { + int removed = pq.remove(); + for (int i = 0; i < map.get(removed); i++) { + nums[idx++] = removed; + } + } + return nums; + } +} diff --git a/Easy/Sort Even and Odd Indices Independently.java b/Easy/Sort Even and Odd Indices Independently.java new file mode 100644 index 00000000..7b7e8203 --- /dev/null +++ b/Easy/Sort Even and Odd Indices Independently.java @@ -0,0 +1,22 @@ +class Solution { + public int[] sortEvenOdd(int[] nums) { + PriorityQueue oddIndices = new PriorityQueue<>((o1, o2) -> o2 - o1); + PriorityQueue evenIndices = new PriorityQueue<>(); + for (int i = 0; i < nums.length; i++) { + if (i % 2 == 0) { + evenIndices.add(nums[i]); + } else { + oddIndices.add(nums[i]); + } + } + int[] result = new int[nums.length]; + for (int i = 0; i < nums.length; i++) { + if (i % 2 == 0) { + result[i] = evenIndices.poll(); + } else { + result[i] = oddIndices.poll(); + } + } + return result; + } +} diff --git a/Easy/Sort Integers by The Number of 1 Bits.java b/Easy/Sort Integers by The Number of 1 Bits.java index d2fc14c3..4b1e7c2c 100644 --- a/Easy/Sort Integers by The Number of 1 Bits.java +++ b/Easy/Sort Integers by The Number of 1 Bits.java @@ -1,9 +1,8 @@ class Solution { public int[] sortByBits(int[] arr) { - return Arrays.stream(arr).boxed() + return Arrays.stream(arr) + .boxed() .sorted(Comparator.comparingInt(Integer::bitCount).thenComparingInt(o -> o)) - .collect(Collectors.toList()) - .stream() .mapToInt(Integer::intValue) .toArray(); } diff --git a/Easy/Sort the People.java b/Easy/Sort the People.java new file mode 100644 index 00000000..03678ec2 --- /dev/null +++ b/Easy/Sort the People.java @@ -0,0 +1,10 @@ +class Solution { + public String[] sortPeople(String[] names, int[] heights) { + return IntStream.range(0, names.length) + .boxed() + .sorted((o1, o2) -> heights[o2] - heights[o1]) + .map(idx -> names[idx]) + .toList() + .toArray(new String[0]); + } +} diff --git a/Easy/Sorting the Sentence.java b/Easy/Sorting the Sentence.java new file mode 100644 index 00000000..6909055c --- /dev/null +++ b/Easy/Sorting the Sentence.java @@ -0,0 +1,18 @@ +class Solution { + public String sortSentence(String s) { + String[] positions = new String[9]; + String[] strs = s.split("\\s+"); + for (String str : strs) { + int digit = Character.getNumericValue(str.charAt(str.length() - 1)); + positions[digit - 1] = str.substring(0, str.length() - 1); + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < positions.length; i++) { + if (positions[i] == null) { + break; + } + sb.append(positions[i]).append(" "); + } + return sb.toString().trim(); + } +} diff --git a/Easy/Special Array I.java b/Easy/Special Array I.java new file mode 100644 index 00000000..5057f626 --- /dev/null +++ b/Easy/Special Array I.java @@ -0,0 +1,10 @@ +class Solution { + public boolean isArraySpecial(int[] nums) { + for (int i = 1; i < nums.length; i++) { + if (nums[i] % 2 == nums[i - 1] % 2) { + return false; + } + } + return true; + } +} diff --git a/Easy/Split Strings by Separator.java b/Easy/Split Strings by Separator.java new file mode 100644 index 00000000..2292a309 --- /dev/null +++ b/Easy/Split Strings by Separator.java @@ -0,0 +1,22 @@ +class Solution { + public List splitWordsBySeparator(List words, char separator) { + List result = new ArrayList<>(); + for (String word : words) { + int startIdx = 0; + int currIdx = 0; + while (currIdx < word.length()) { + if (word.charAt(currIdx) == separator) { + if (currIdx - startIdx > 0) { + result.add(word.substring(startIdx, currIdx)); + } + startIdx = currIdx + 1; + } + currIdx++; + } + if (currIdx - startIdx > 0) { + result.add(word.substring(startIdx, currIdx)); + } + } + return result; + } +} diff --git a/Easy/Split With Minimum Sum.java b/Easy/Split With Minimum Sum.java new file mode 100644 index 00000000..3f816605 --- /dev/null +++ b/Easy/Split With Minimum Sum.java @@ -0,0 +1,22 @@ +class Solution { + public int splitNum(int num) { + List digits = new ArrayList<>(); + while (num > 0) { + digits.add(num % 10); + num /= 10; + } + Collections.sort(digits); + int numOne = 0; + int numTwo = 0; + boolean flag = true; + for (int digit : digits) { + if (flag) { + numOne = numOne * 10 + digit; + } else { + numTwo = numTwo * 10 + digit; + } + flag = !flag; + } + return numOne + numTwo; + } +} diff --git a/Easy/Split the Array.java b/Easy/Split the Array.java new file mode 100644 index 00000000..607a2de0 --- /dev/null +++ b/Easy/Split the Array.java @@ -0,0 +1,10 @@ +class Solution { + public boolean isPossibleToSplit(int[] nums) { + return Arrays.stream(nums) + .boxed() + .collect(Collectors.groupingBy(Function.identity(), HashMap::new, Collectors.counting())) + .values() + .stream() + .allMatch(v -> v <= 2); + } +} diff --git a/Easy/SqrtX.java b/Easy/SqrtX.java index 51c13b9c..9c96e058 100644 --- a/Easy/SqrtX.java +++ b/Easy/SqrtX.java @@ -3,21 +3,19 @@ public int mySqrt(int x) { if (x < 2) { return x; } - int start = 2; - int end = x / 2; - while (start <= end) { - int mid = start + (end - start) / 2; - long num = (long) mid * mid; - if (num > x) { - end = mid - 1; - } - else if (num < x) { - start = mid + 1; - } - else { + int left = 2; + int right = x / 2; + while (left <= right) { + int mid = (left + right) / 2; + long square = ((long) mid) * mid; + if (square > x) { + right = mid - 1; + } else if (square < x) { + left = mid + 1; + } else { return mid; } } - return end; + return right; } } diff --git a/Easy/Squares of a Sorted Array.java b/Easy/Squares of a Sorted Array.java index efd36968..08f5faa6 100644 --- a/Easy/Squares of a Sorted Array.java +++ b/Easy/Squares of a Sorted Array.java @@ -1,35 +1,18 @@ class Solution { - public int[] sortedSquares(int[] A) { - int posIdx = A.length; - for (int i = 0; i < A.length; i++) { - if (A[i] >= 0) { - posIdx = i; - break; - } - } - int[] ans = new int[A.length]; - int negIdx = posIdx - 1; - int idx = 0; - while (negIdx >= 0 || posIdx < A.length) { - if (negIdx >= 0 && (posIdx >= 0 && posIdx < A.length)) { - if (A[negIdx] * A[negIdx] > A[posIdx] * A[posIdx]) { - ans[idx++] = A[posIdx] * A[posIdx]; - posIdx++; - } - else { - ans[idx++] = A[negIdx] * A[negIdx]; - negIdx--; + public int[] sortedSquares(int[] nums) { + int n = nums.length; + int start = 0; + int end = n - 1; + int[] result = new int[n]; + for (int i = n - 1; i >= 0; i--) { + if (Math.abs(nums[start]) >= Math.abs(nums[end])) { + result[i] = nums[start] * nums[start]; + start++; + } else { + result[i] = nums[end] * nums[end]; + end--; + } } - } - else if (negIdx >= 0 && posIdx >= A.length) { - ans[idx++] = A[negIdx] * A[negIdx]; - negIdx--; - } - else { - ans[idx++] = A[posIdx] * A[posIdx]; - posIdx++; - } + return result; } - return ans; - } } diff --git a/Easy/String Compression.java b/Easy/String Compression.java deleted file mode 100644 index 6b21d22e..00000000 --- a/Easy/String Compression.java +++ /dev/null @@ -1,23 +0,0 @@ -class Solution { - public int compress(char[] chars) { - int start = 0; - int end = 0; - int n = chars.length; - while (end < n) { - char c = chars[end]; - int count = 0; - while (end < n && chars[end] == c) { - end++; - count++; - } - chars[start++] = c; - if (count > 1) { - String countStr = String.valueOf(count); - for (char countC : countStr.toCharArray()) { - chars[start++] = countC; - } - } - } - return start; - } -} diff --git a/Easy/Strobogrammatic Number.java b/Easy/Strobogrammatic Number.java index c258a0c2..76ceb310 100644 --- a/Easy/Strobogrammatic Number.java +++ b/Easy/Strobogrammatic Number.java @@ -2,13 +2,11 @@ class Solution { public boolean isStrobogrammatic(String num) { StringBuilder sb = new StringBuilder(); for (char c : num.toCharArray()) { - if (c == '0' || c == '1' || c == '8') { - sb.append(c); - } - else if (c == '6' || c == '9') { + if (c == '6' || c == '9') { sb.append(c == '6' ? '9' : '6'); - } - else { + } else if (c == '0' || c == '8' || c == '1') { + sb.append(c); + } else { return false; } } diff --git a/Easy/Strong Password Checker II.java b/Easy/Strong Password Checker II.java new file mode 100644 index 00000000..56e82a98 --- /dev/null +++ b/Easy/Strong Password Checker II.java @@ -0,0 +1,25 @@ +class Solution { + public boolean strongPasswordCheckerII(String password) { + boolean lowerCaseFound = false; + boolean upperCaseFound = false; + boolean digitFound = false; + boolean specialCharFound = false; + String specialChars = "!@#$%^&*()-+"; + for (int i = 0; i < password.length(); i++) { + char c = password.charAt(i); + if (specialChars.indexOf(c) != -1) { + specialCharFound = true; + } else if (Character.isDigit(c)) { + digitFound = true; + } else if (Character.isUpperCase(c)) { + upperCaseFound = true; + } else if (Character.isLowerCase(c)) { + lowerCaseFound = true; + } + if (i > 0 && password.charAt(i - 1) == c) { + return false; + } + } + return password.length() >= 8 && lowerCaseFound && upperCaseFound && digitFound && specialCharFound; + } +} diff --git a/Easy/Student Attendance Record I.java b/Easy/Student Attendance Record I.java index 0278cb49..75021837 100644 --- a/Easy/Student Attendance Record I.java +++ b/Easy/Student Attendance Record I.java @@ -1,16 +1,16 @@ class Solution { public boolean checkRecord(String s) { int absentCount = 0; - for (int i = 0; i< s.length(); i++) { - if (s.charAt(i) == 'A') { + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == 'A') { absentCount++; - } - else if (s.charAt(i) == 'L') { - if (i + 1 < s.length() && i + 2 < s.length() && s.charAt(i + 1) == 'L' && s.charAt(i + 2) == 'L') { + } else if (c == 'L') { + if (i > 1 && s.charAt(i - 1) == 'L' && s.charAt(i - 2) == 'L') { return false; } } } - return absentCount <= 1; + return absentCount < 2; } } diff --git a/Easy/Subarrays Distinct Element Sum of Squares I.java b/Easy/Subarrays Distinct Element Sum of Squares I.java new file mode 100644 index 00000000..fa7cee6a --- /dev/null +++ b/Easy/Subarrays Distinct Element Sum of Squares I.java @@ -0,0 +1,15 @@ +class Solution { + public int sumCounts(List nums) { + int sum = 0; + int n = nums.size(); + for (int i = 0; i < n; i++) { + Set set = new HashSet<>(); + for (int j = i; j < n; j++) { + set.add(nums.get(j)); + int size = set.size(); + sum += size * size; + } + } + return sum; + } +} diff --git a/Easy/Subdomain Visit Count.java b/Easy/Subdomain Visit Count.java deleted file mode 100644 index 5c99417d..00000000 --- a/Easy/Subdomain Visit Count.java +++ /dev/null @@ -1,21 +0,0 @@ -class Solution { - public List subdomainVisits(String[] cpdomains) { - Map map = new HashMap<>(); - for (String domain : cpdomains) { - String[] strs = domain.split("\\s+"); - int count = Integer.parseInt(strs[0]); - String[] lowerDomains = strs[1].split("\\."); - StringBuilder sb = new StringBuilder(); - for (int i = lowerDomains.length - 1; i >= 0; i--) { - sb.insert(0, lowerDomains[i]); - map.put(sb.toString(), map.getOrDefault(sb.toString(), 0) + count); - sb.insert(0, '.'); - } - } - List list = new ArrayList<>(); - for (String key : map.keySet()) { - list.add(map.get(key) + " " + key); - } - return list; - } -} diff --git a/Easy/Substrings of Size Three with Distinct Characters.java b/Easy/Substrings of Size Three with Distinct Characters.java new file mode 100644 index 00000000..9e54553f --- /dev/null +++ b/Easy/Substrings of Size Three with Distinct Characters.java @@ -0,0 +1,20 @@ +class Solution { + public int countGoodSubstrings(String s) { + Map map = new HashMap<>(); + int count = 0; + for (int i = 0; i < Math.min(s.length(), 2); i++) { + map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1); + } + for (int i = 2; i < s.length(); i++) { + map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1); + if (map.size() == 3) { + count++; + } + map.put(s.charAt(i - 2), map.getOrDefault(s.charAt(i - 2), 0) - 1); + if (map.get(s.charAt(i - 2)) == 0) { + map.remove(s.charAt(i - 2)); + } + } + return count; + } +} diff --git a/Easy/Subtract the Product and Sum of Digits of an Integer.java b/Easy/Subtract the Product and Sum of Digits of an Integer.java index 462d8f60..d08e41f7 100644 --- a/Easy/Subtract the Product and Sum of Digits of an Integer.java +++ b/Easy/Subtract the Product and Sum of Digits of an Integer.java @@ -1,17 +1,12 @@ class Solution { public int subtractProductAndSum(int n) { int sum = 0; - int copy = n; - while (copy > 0) { - sum += copy % 10; - copy /= 10; + int product = 1; + while (n > 0) { + sum += n % 10; + product *= n % 10; + n /= 10; } - int prod = 1; - copy = n; - while (copy > 0) { - prod *= copy % 10; - copy /= 10; - } - return prod - sum; + return product - sum; } } diff --git a/Easy/Subtree of Another Tree.java b/Easy/Subtree of Another Tree.java index f132ee85..c0e307eb 100644 --- a/Easy/Subtree of Another Tree.java +++ b/Easy/Subtree of Another Tree.java @@ -4,30 +4,31 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public boolean isSubtree(TreeNode s, TreeNode t) { - if (s == null) { + public boolean isSubtree(TreeNode root, TreeNode subRoot) { + if (root == null) { return false; } - if (helper(s, t)) { - return true; - } - return isSubtree(s.left, t) || isSubtree(s.right, t); + boolean result = root.val == subRoot.val && isSubtreeHelper(root, subRoot); + return result || isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot); } - private boolean helper(TreeNode s, TreeNode t) { - if (s == null && t == null) { + private boolean isSubtreeHelper(TreeNode root, TreeNode subRoot) { + if (root == null && subRoot == null) { return true; } - if ((s == null && t != null) || (s != null && t == null)) { - return false; - } - if (s.val != t.val) { + if (root == null || subRoot == null) { return false; } - return helper(s.left, t.left) && helper(s.right, t.right); + return root.val == subRoot.val && isSubtreeHelper(root.left, subRoot.left) && isSubtreeHelper(root.right, subRoot.right); } } diff --git a/Easy/Sum Of Two Integers.java b/Easy/Sum Of Two Integers.java new file mode 100644 index 00000000..c1a70d9a --- /dev/null +++ b/Easy/Sum Of Two Integers.java @@ -0,0 +1,8 @@ +public class Solution { + public int getSum(int x, int y) { + if (y == 0) + return x; + else + return getSum( x ^ y, (x & y) << 1); + } +} diff --git a/Easy/Sum of All Subset XOR Totals.java b/Easy/Sum of All Subset XOR Totals.java new file mode 100644 index 00000000..fe82567a --- /dev/null +++ b/Easy/Sum of All Subset XOR Totals.java @@ -0,0 +1,14 @@ +class Solution { + public int subsetXORSum(int[] nums) { + return recurse(nums, 0, 0); + } + + private int recurse(int[] nums, int idx, int currXor) { + if (idx == nums.length) { + return currXor; + } + int performXor = recurse(nums, idx + 1, currXor ^ nums[idx]); + int notPerformXor = recurse(nums, idx + 1, currXor); + return performXor + notPerformXor; + } +} diff --git a/Easy/Sum of Digits in Base K.java b/Easy/Sum of Digits in Base K.java new file mode 100644 index 00000000..9775701b --- /dev/null +++ b/Easy/Sum of Digits in Base K.java @@ -0,0 +1,10 @@ +class Solution { + public int sumBase(int n, int k) { + int digitSum = 0; + while (n > 0) { + digitSum += n % k; + n /= k; + } + return digitSum; + } +} diff --git a/Easy/Sum of Digits of String After Convert.java b/Easy/Sum of Digits of String After Convert.java new file mode 100644 index 00000000..3b78aaae --- /dev/null +++ b/Easy/Sum of Digits of String After Convert.java @@ -0,0 +1,18 @@ +class Solution { + public int getLucky(String s, int k) { + StringBuilder sb = new StringBuilder(); + for (char c : s.toCharArray()) { + sb.append(c - 'a' + 1); + } + while (k-- > 0) { + String temp = sb.toString(); + sb.setLength(0); + int val = 0; + for (char c : temp.toCharArray()) { + val += Character.getNumericValue(c); + } + sb.append(val); + } + return Integer.parseInt(sb.toString()); + } +} diff --git a/Easy/Sum of Even Numbers After Queries.java b/Easy/Sum of Even Numbers After Queries.java deleted file mode 100644 index 8b7d1d27..00000000 --- a/Easy/Sum of Even Numbers After Queries.java +++ /dev/null @@ -1,21 +0,0 @@ -class Solution { - public int[] sumEvenAfterQueries(int[] A, int[][] queries) { - int sum = 0; - for (int num : A) { - sum += num % 2 == 0 ? num : 0; - } - int[] ans = new int[queries.length]; - for (int i = 0; i < queries.length; i++) { - int newVal = A[queries[i][1]] + queries[i][0]; - if (A[queries[i][1]] % 2 == 0) { - sum -= A[queries[i][1]]; - } - A[queries[i][1]] = newVal; - if (A[queries[i][1]] % 2 == 0) { - sum += newVal; - } - ans[i] = sum; - } - return ans; - } -} diff --git a/Easy/Sum of Left Leaves.java b/Easy/Sum of Left Leaves.java new file mode 100644 index 00000000..622dd1c4 --- /dev/null +++ b/Easy/Sum of Left Leaves.java @@ -0,0 +1,43 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public int sumOfLeftLeaves(TreeNode root) { + int sum = 0; + Queue queue = new LinkedList<>(); + queue.add(new TreeNode[]{root, null}); + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + TreeNode[] removed = queue.remove(); + TreeNode node = removed[0]; + TreeNode parent = removed[1]; + if (node.left == null && node.right == null) { + if (parent != null && parent.left == node) { + sum += node.val; + } + } else { + if (node.left != null) { + queue.add(new TreeNode[]{node.left, node}); + } + if (node.right != null) { + queue.add(new TreeNode[]{node.right, node}); + } + } + } + } + return sum; + } +} diff --git a/Easy/Sum of Root To Leaf Binary Numbers.java b/Easy/Sum of Root To Leaf Binary Numbers.java index 135a6c6a..d49907f2 100644 --- a/Easy/Sum of Root To Leaf Binary Numbers.java +++ b/Easy/Sum of Root To Leaf Binary Numbers.java @@ -15,32 +15,46 @@ */ class Solution { public int sumRootToLeaf(TreeNode root) { - int[] sum = {0}; - helper(root, new StringBuilder(), sum); - return sum[0]; + Queue queue = new LinkedList<>(); + queue.add(new NodeToBinaryRepresentation(root, new StringBuilder())); + int sum = 0; + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + NodeToBinaryRepresentation removed = queue.remove(); + StringBuilder sb = new StringBuilder().append(removed.sb.toString()).append(removed.node.val); + if (removed.node.left == null && removed.node.right == null) { + sum += getIntegerValue(sb.toString()); + } else { + if (removed.node.left != null) { + queue.add(new NodeToBinaryRepresentation(removed.node.left, sb)); + } + if (removed.node.right != null) { + queue.add(new NodeToBinaryRepresentation(removed.node.right, sb)); + } + } + } + } + return sum; } - private void helper(TreeNode root, StringBuilder sb, int[] sum) { - if (root == null) { - return; - } - sb.append(root.val); - if (root.left == null && root.right == null) { - sum[0] += getDecimalValue(sb.toString()); - } - else { - helper(root.left, new StringBuilder(sb.toString()), sum); - helper(root.right, new StringBuilder(sb.toString()), sum); + private int getIntegerValue(String s) { + int value = 0; + int multiplier = 1; + for (int i = s.length() - 1; i >= 0; i--) { + value += Character.getNumericValue(s.charAt(i)) * multiplier; + multiplier *= 2; } + return value; } - private int getDecimalValue(String s) { - int val = 0; - int mul = 1; - for (int i = s.length() - 1; i >= 0; i--) { - val += mul * (s.charAt(i) == '1' ? 1 : 0); - mul *= 2; + private static class NodeToBinaryRepresentation { + TreeNode node; + StringBuilder sb; + + public NodeToBinaryRepresentation(TreeNode node, StringBuilder sb) { + this.node = node; + this.sb = sb; } - return val; } } diff --git a/Easy/Sum of Squares of Special Elements.java b/Easy/Sum of Squares of Special Elements.java new file mode 100644 index 00000000..2072eee5 --- /dev/null +++ b/Easy/Sum of Squares of Special Elements.java @@ -0,0 +1,8 @@ +class Solution { + public int sumOfSquares(int[] nums) { + return IntStream.range(0, nums.length) + .filter(i -> nums.length % (i + 1) == 0) + .map(i -> nums[i] * nums[i]) + .sum(); + } +} diff --git a/Easy/Sum of Unique Elements.java b/Easy/Sum of Unique Elements.java new file mode 100644 index 00000000..50782e0c --- /dev/null +++ b/Easy/Sum of Unique Elements.java @@ -0,0 +1,10 @@ +import java.util.Map.Entry; + +class Solution { + public int sumOfUnique(int[] nums) { + return Arrays.stream(nums).boxed() + .collect(Collectors.groupingBy(Function.identity(), HashMap::new, Collectors.counting())) + .entrySet().stream().filter(e -> e.getValue().equals(1L)).map( + Entry::getKey).reduce(0, Integer::sum); + } +} diff --git a/Easy/Sum of Values at Indices With K Set Bits.java b/Easy/Sum of Values at Indices With K Set Bits.java new file mode 100644 index 00000000..598f65c1 --- /dev/null +++ b/Easy/Sum of Values at Indices With K Set Bits.java @@ -0,0 +1,8 @@ +class Solution { + public int sumIndicesWithKSetBits(List nums, int k) { + return IntStream.range(0, nums.size()) + .filter(idx -> Integer.bitCount(idx) == k) + .map(idx -> nums.get(idx)) + .sum(); + } +} diff --git a/Easy/Sum of Variable Length Subarrays.java b/Easy/Sum of Variable Length Subarrays.java new file mode 100644 index 00000000..5dc7d585 --- /dev/null +++ b/Easy/Sum of Variable Length Subarrays.java @@ -0,0 +1,19 @@ +class Solution { + public int subarraySum(int[] nums) { + int n = nums.length; + int[] prefixSum = new int[n]; + int sum = 0; + int result = 0; + for (int i = 0; i < n; i++) { + sum += nums[i]; + prefixSum[i] = sum; + int start = Math.max(0, i - nums[i]); + int subarraySum = prefixSum[i]; + if (start > 0) { + subarraySum -= prefixSum[start - 1]; + } + result += subarraySum; + } + return result; + } +} diff --git a/Easy/Sum of left leaves.java b/Easy/Sum of left leaves.java deleted file mode 100644 index 7197aa1c..00000000 --- a/Easy/Sum of left leaves.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode() {} - * TreeNode(int val) { this.val = val; } - * TreeNode(int val, TreeNode left, TreeNode right) { - * this.val = val; - * this.left = left; - * this.right = right; - * } - * } - */ -class Solution { - public int sumOfLeftLeaves(TreeNode root) { - if (root == null) { - return 0; - } - int sum = 0; - Queue queue = new LinkedList<>(); - queue.add(new TreeNode[]{root, null}); - while (!queue.isEmpty()) { - TreeNode[] removed = queue.remove(); - if (removed[0].left == null && removed[0].right == null) { - if (removed[1] != null && removed[1].left == removed[0]) { - sum += removed[0].val; - } - } - else { - if (removed[0].left != null) { - queue.add(new TreeNode[]{removed[0].left, removed[0]}); - } - if (removed[0].right != null) { - queue.add(new TreeNode[]{removed[0].right, removed[0]}); - } - } - } - return sum; - } -} diff --git a/Easy/Sum of square numbers.java b/Easy/Sum of square numbers.java deleted file mode 100644 index cd8e6598..00000000 --- a/Easy/Sum of square numbers.java +++ /dev/null @@ -1,20 +0,0 @@ -class Solution { - public boolean judgeSquareSum(int c) { - int a = 0; - int b = (int)Math.sqrt(c); - - while (a <= b) { - int temp = a*a + b*b; - if (temp < c) { - a++; - } - else if (temp > c) { - b--; - } - else { - return true; - } - } - return false; - } -} diff --git a/Easy/Summary Ranges.java b/Easy/Summary Ranges.java new file mode 100644 index 00000000..0de1dc7b --- /dev/null +++ b/Easy/Summary Ranges.java @@ -0,0 +1,16 @@ +class Solution { + public List summaryRanges(int[] nums) { + List result = new ArrayList<>(); + int idx = 0; + while (idx < nums.length) { + int startIdx = idx; + int endIdx = idx; + idx++; + while (idx < nums.length && nums[idx] - nums[idx - 1] == 1) { + endIdx = idx++; + } + result.add(startIdx == endIdx ? String.valueOf(nums[startIdx]) : nums[startIdx] + "->" + nums[endIdx]); + } + return result; + } +} diff --git a/Easy/Symmetric Tree.java b/Easy/Symmetric Tree.java index c50a5256..929d6ade 100644 --- a/Easy/Symmetric Tree.java +++ b/Easy/Symmetric Tree.java @@ -4,27 +4,38 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public boolean isSymmetric(TreeNode root) { - if (root == null) { - return true; + public boolean isSymmetric(TreeNode root) { + Queue queue = new LinkedList<>(); + queue.add(new TreeNode[]{root.left, root.right}); + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + TreeNode[] removed = queue.remove(); + TreeNode nodeOne = removed[0]; + TreeNode nodeTwo = removed[1]; + if (nodeOne == null && nodeTwo == null) { + continue; + } + if (nodeOne == null || nodeTwo == null) { + return false; + } + if (nodeOne.val != nodeTwo.val) { + return false; + } + queue.add(new TreeNode[]{nodeOne.left, nodeTwo.right}); + queue.add(new TreeNode[]{nodeOne.right, nodeTwo.left}); + } + } + return true; } - return helper(root.left, root.right); - } - - private boolean helper(TreeNode r, TreeNode l) { - if (r == null && l == null) { - return true; - } - if (r == null || l == null) { - return false; - } - if (r.val != l.val) { - return false; - } - return helper(l.left, r.right) && helper(l.right, r.left); - } } diff --git a/Easy/Take Gifts From the Richest Pile.java b/Easy/Take Gifts From the Richest Pile.java new file mode 100644 index 00000000..ea754818 --- /dev/null +++ b/Easy/Take Gifts From the Richest Pile.java @@ -0,0 +1,17 @@ +class Solution { + public long pickGifts(int[] gifts, int k) { + PriorityQueue pq = new PriorityQueue<>((a, b) -> b - a); + long totalGifts = 0; + for (int gift : gifts) { + pq.add(gift); + totalGifts += gift; + } + while (k-- > 0) { + int removedGift = pq.poll(); + int remainingGift = (int) Math.sqrt(removedGift); + totalGifts -= removedGift - remainingGift; + pq.add(remainingGift); + } + return totalGifts; + } +} diff --git a/Easy/Teemo Attacking.java b/Easy/Teemo Attacking.java new file mode 100644 index 00000000..45e33622 --- /dev/null +++ b/Easy/Teemo Attacking.java @@ -0,0 +1,11 @@ +class Solution { + public int findPoisonedDuration(int[] timeSeries, int duration) { + int totalDuration = 0; + int prevTime = timeSeries[0]; + for (int i = 1; i < timeSeries.length; i++) { + totalDuration += Math.min(duration, timeSeries[i] - prevTime); + prevTime = timeSeries[i]; + } + return totalDuration + duration; + } +} diff --git a/Easy/The Employee That Worked on the Longest Task.java b/Easy/The Employee That Worked on the Longest Task.java new file mode 100644 index 00000000..e4d30e69 --- /dev/null +++ b/Easy/The Employee That Worked on the Longest Task.java @@ -0,0 +1,20 @@ +class Solution { + public int hardestWorker(int n, int[][] logs) { + int maxTime = 0; + int startTime = 0; + int hardestWorkerId = 0; + for (int[] log : logs) { + int taskTime = log[1] - startTime; + startTime = log[1]; + if (taskTime > maxTime) { + maxTime = taskTime; + hardestWorkerId = log[0]; + } else if (taskTime == maxTime) { + if (hardestWorkerId > log[0]) { + hardestWorkerId = log[0]; + } + } + } + return hardestWorkerId; + } +} diff --git a/Easy/The K Weakest Rows in a Matrix.java b/Easy/The K Weakest Rows in a Matrix.java index 4da5a15e..a4a52ad7 100644 --- a/Easy/The K Weakest Rows in a Matrix.java +++ b/Easy/The K Weakest Rows in a Matrix.java @@ -1,40 +1,28 @@ class Solution { - public int[] kWeakestRows(int[][] mat, int k) { - Map map = new HashMap<>(); - for (int i = 0; i < mat.length; i++) { - map.put(i, getLastIndex(mat[i], 0, mat[i].length - 1) + 1); - } - PriorityQueue pq = new PriorityQueue(new Comparator(){ - public int compare(Integer o1, Integer o2) { - int c = map.get(o1) - map.get(o2); - if (c != 0) { - return c; + public int[] kWeakestRows(int[][] mat, int k) { + PriorityQueue pq = + new PriorityQueue<>(Comparator.comparingInt((int[] o) -> o[1]).thenComparingInt(o -> o[0])); + for (int i = 0; i < mat.length; i++) { + pq.add(new int[]{i, findNumberOfSoldiers(mat[i])}); } - return o1 - o2; - } - }); - for (int i = 0; i < mat.length; i++) { - pq.add(i); - } - int[] ans = new int[k]; - for (int i = 0; i < k; i++) { - ans[i] = pq.poll(); + int[] result = new int[k]; + for (int i = 0; i < k && !pq.isEmpty(); i++){ + result[i] = pq.poll()[0]; + } + return result; } - return ans; - } - - private int getLastIndex(int[] arr, int start, int end) { - int idx = -1; - while (start <= end) { - int mid = (start + end) / 2; - if (arr[mid] == 1) { - idx = Math.max(idx, mid); - start = mid + 1; - } - else { - end = mid - 1; - } + + private int findNumberOfSoldiers(int[] row) { + int left = 0; + int right = row.length - 1; + while (left <= right) { + int mid = (left + right) / 2; + if (row[mid] == 0) { + right = mid - 1; + } else { + left = mid + 1; + } + } + return right < 0 ? 0 : left; } - return idx; - } } diff --git a/Easy/Three Divisors.java b/Easy/Three Divisors.java new file mode 100644 index 00000000..7b755498 --- /dev/null +++ b/Easy/Three Divisors.java @@ -0,0 +1,14 @@ +class Solution { + public boolean isThree(int n) { + int numOfDivisors = 0; + for (int i = 1; i <= n; i++) { + if (n % i == 0) { + numOfDivisors++; + } + if (numOfDivisors > 3) { + return false; + } + } + return numOfDivisors == 3; + } +} diff --git a/Easy/Time Needed to Buy Tickets.java b/Easy/Time Needed to Buy Tickets.java new file mode 100644 index 00000000..8f7e1a57 --- /dev/null +++ b/Easy/Time Needed to Buy Tickets.java @@ -0,0 +1,13 @@ +class Solution { + public int timeRequiredToBuy(int[] tickets, int k) { + int timeRequired = 0; + for(int i = 0;i < tickets.length; i++){ + if(i <= k){ + timeRequired += Math.min(tickets[k], tickets[i]); + } else { + timeRequired += Math.min(tickets[k] - 1, tickets[i]); + } + } + return timeRequired; + } +} diff --git a/Easy/To Lower Case.java b/Easy/To Lower Case.java index 623cb4d6..0640e6f0 100644 --- a/Easy/To Lower Case.java +++ b/Easy/To Lower Case.java @@ -1,15 +1,6 @@ class Solution { - public String toLowerCase(String str) { - StringBuilder sb = new StringBuilder(); - for (char c : str.toCharArray()) { - int ascii = (int) c; - if (c >= 65 && c <= 90) { - sb.append((char) (c - 65 + 97)); - } - else { - sb.append(c); - } - } - return sb.toString(); + public String toLowerCase(String s) { + return s.chars().mapToObj(c -> (char) c).map(Character::toLowerCase).map(String::valueOf) + .collect(Collectors.joining()); } } diff --git a/Easy/Toeplitz Matrix.java b/Easy/Toeplitz Matrix.java index c5422a95..bccbd515 100644 --- a/Easy/Toeplitz Matrix.java +++ b/Easy/Toeplitz Matrix.java @@ -1,11 +1,12 @@ class Solution { - public boolean isToeplitzMatrix(int[][] matrix) { - for (int i=0;i R) { - return trimBST(root.left, L, R); - } - else { - root.left = trimBST(root.left, L, R); - root.right = trimBST(root.right, L, R); - return root; - } - } -} diff --git a/Easy/Truncate Sentence.java b/Easy/Truncate Sentence.java new file mode 100644 index 00000000..3b910dac --- /dev/null +++ b/Easy/Truncate Sentence.java @@ -0,0 +1,12 @@ +class Solution { + public String truncateSentence(String s, int k) { + int idx = 0; + while (idx < s.length() && k > 0) { + if (s.charAt(idx) == ' ') { + k--; + } + idx++; + } + return s.substring(0, (idx == s.length() ? idx : idx - 1)); + } +} diff --git a/Easy/Two City Scheduling.java b/Easy/Two City Scheduling.java deleted file mode 100644 index 6bcb5602..00000000 --- a/Easy/Two City Scheduling.java +++ /dev/null @@ -1,15 +0,0 @@ -class Solution { - public int twoCitySchedCost(int[][] costs) { - Arrays.sort(costs, new Comparator(){ - public int compare(int[] o1, int[] o2) { - return o1[0] - o1[1] - (o2[0] - o2[1]); - } - }); - int total = 0; - int n = costs.length / 2; - for (int i = 0; i < n; i++) { - total += costs[i][0] + costs[i + n][1]; - } - return total; - } -} diff --git a/Easy/Two Furthest Houses With Different Colors.java b/Easy/Two Furthest Houses With Different Colors.java new file mode 100644 index 00000000..af52bca8 --- /dev/null +++ b/Easy/Two Furthest Houses With Different Colors.java @@ -0,0 +1,13 @@ +class Solution { + public int maxDistance(int[] colors) { + int startIdx = 0; + int endIdx = colors.length - 1; + while (colors[0] == colors[endIdx]) { + endIdx--; + } + while (colors[colors.length - 1] == colors[startIdx]) { + startIdx++; + } + return Math.max(colors.length - 1 - startIdx, endIdx); + } +} diff --git a/Easy/Two Out of Three.java b/Easy/Two Out of Three.java new file mode 100644 index 00000000..7deb6a0b --- /dev/null +++ b/Easy/Two Out of Three.java @@ -0,0 +1,19 @@ +class Solution { + public List twoOutOfThree(int[] nums1, int[] nums2, int[] nums3) { + Map> map = new HashMap<>(); + updateMap(map, nums1, "1"); + updateMap(map, nums2, "2"); + updateMap(map, nums3, "3"); + return map.entrySet() + .stream() + .filter(entry -> entry.getValue().size() > 1) + .map(entry -> entry.getKey()) + .collect(Collectors.toList()); + } + + private void updateMap(Map> map, int[] nums, String key) { + for (int num : nums) { + map.computeIfAbsent(num, k -> new HashSet<>()).add(key); + } + } +} diff --git a/Easy/Two Sum II.java b/Easy/Two Sum II.java deleted file mode 100644 index 6d313038..00000000 --- a/Easy/Two Sum II.java +++ /dev/null @@ -1,19 +0,0 @@ -class Solution { - public int[] twoSum(int[] numbers, int target) { - int[] ans = new int[2]; - int i = 0; - int j = numbers.length-1; - while (numbers[i] + numbers[j] != target) { - if (numbers[i] + numbers[j] > target) { - j--; - } - else { - i++; - } - } - ans[0] = i+1; - ans[1] = j+1; - - return ans; - } -} diff --git a/Easy/Two Sum IV - Input is a BST.java b/Easy/Two Sum IV - Input is a BST.java index 84f1f8cd..c55e4b47 100644 --- a/Easy/Two Sum IV - Input is a BST.java +++ b/Easy/Two Sum IV - Input is a BST.java @@ -4,46 +4,42 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public boolean findTarget(TreeNode root, int k) { - Stack stack = new Stack<>(); - while (root != null) { - stack.push(root); - root = root.left; - } - - Set set = new HashSet<>(); - int min = popStack(stack); - set.add(min); - - while (!stack.isEmpty()) { - int num = popStack(stack); - if (set.contains(k-num)) { - return true; - } - - if (min + num > k) { - return false; - } - - set.add(num); - } - - return false; + public boolean findTarget(TreeNode root, int k) { + if (root == null) { + return false; + } + Stack stack = new Stack<>(); + Set set = new HashSet<>(); + while (root != null) { + if (set.contains(k - root.val)) { + return true; + } + stack.push(root); + set.add(root.val); + root = root.left; } - - private int popStack(Stack stack) { - TreeNode n = stack.pop(); - TreeNode right = n.right; - - while (right != null) { - stack.push(right); - right = right.left; + while (!stack.isEmpty()) { + TreeNode removed = stack.pop(); + TreeNode rightNode = removed.right; + while (rightNode != null) { + if (set.contains(k - rightNode.val)) { + return true; } - - return n.val; + stack.push(rightNode); + set.add(rightNode.val); + rightNode = rightNode.left; + } } + return false; + } } diff --git a/Easy/Two Sum Less Than K.java b/Easy/Two Sum Less Than K.java index 7a74f60d..5acfd8dc 100644 --- a/Easy/Two Sum Less Than K.java +++ b/Easy/Two Sum Less Than K.java @@ -1,17 +1,22 @@ class Solution { - public int twoSumLessThanK(int[] A, int K) { - int maxSum = -1; - TreeSet set = new TreeSet<>(); - for (int i = 0; i < A.length; i++) { - int diff = K - A[i]; - if (diff > 0) { - Integer half = set.lower(diff); - if (half != null) { - maxSum = Math.max(maxSum, A[i] + half); + public int twoSumLessThanK(int[] nums, int k) { + int[] counter = new int[1001]; + for (int num : nums) { + counter[num]++; + } + int result = -1; + int left = 1; + int right = 1000; + while (left <= right) { + if (left + right >= k || counter[right] == 0) { + right--; + } else { + if (counter[left] > (left == right ? 1 : 0)) { + result = Math.max(result, left + right); } + left++; } - set.add(A[i]); } - return maxSum; + return result; } } diff --git a/Easy/Type of Triangle II.java b/Easy/Type of Triangle II.java new file mode 100644 index 00000000..09f0cb88 --- /dev/null +++ b/Easy/Type of Triangle II.java @@ -0,0 +1,15 @@ +class Solution { + public String triangleType(int[] nums) { + Arrays.sort(nums); + if (nums[0] + nums[1] <= nums[2]) { + return "none"; + } + if (nums[0] == nums[1] && nums[1] == nums[2]) { + return "equilateral"; + } + if (nums[0] == nums[1] || nums[1] == nums[2] || nums[0] == nums[2]) { + return "isosceles"; + } + return "scalene"; + } +} diff --git a/Easy/Ugly Number.java b/Easy/Ugly Number.java index e8d27ea0..345df6c7 100644 --- a/Easy/Ugly Number.java +++ b/Easy/Ugly Number.java @@ -1,23 +1,11 @@ class Solution { - public boolean isUgly(int num) { - if (num <= 0) { - return false; - } - long lNum = (long) num; - while (lNum > 1) { - if (lNum % 2 == 0) { - lNum /= 2; - } - else if (lNum % 3 == 0) { - lNum /= 3; - } - else if (lNum % 5 == 0) { - lNum /= 5; - } - else { - return false; + public boolean isUgly(int n) { + int[] primes = {2, 3, 5}; + for (int i = 0; i < primes.length; i++) { + while (n > 1 && n % primes[i] == 0) { + n /= primes[i]; } } - return true; + return n == 1; } } diff --git a/Easy/Uncommon Words from Two Sentences.java b/Easy/Uncommon Words from Two Sentences.java index 4693b5c9..3b7eab9e 100644 --- a/Easy/Uncommon Words from Two Sentences.java +++ b/Easy/Uncommon Words from Two Sentences.java @@ -1,19 +1,20 @@ class Solution { - public static String[] uncommonFromSentences(String A, String B) { - Map map = Arrays. - stream((A + " " + B). - split("\\s+")). - collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); - - List uncommon = map. - entrySet(). - stream(). - filter(e -> e.getValue() == 1). - map(e -> e.getKey()). - collect(Collectors.toList()); - - String[] ans = new String[uncommon.size()]; - - return uncommon.toArray(ans); + public String[] uncommonFromSentences(String s1, String s2) { + Map map = new HashMap<>(); + String[] wordsOne = s1.split("\\s+"); + for (String word : wordsOne) { + map.put(word, map.getOrDefault(word, 0) + 1); } + String[] wordsTwo = s2.split("\\s+"); + for (String word : wordsTwo) { + map.put(word, map.getOrDefault(word, 0) + 1); + } + List result = new ArrayList<>(); + for (String key : map.keySet()) { + if (map.get(key) == 1) { + result.add(key); + } + } + return result.toArray(new String[]{}); + } } diff --git a/Easy/Unique Email Addresses.java b/Easy/Unique Email Addresses.java index 871d1a0e..eb3da5d5 100644 --- a/Easy/Unique Email Addresses.java +++ b/Easy/Unique Email Addresses.java @@ -1,37 +1,13 @@ class Solution { public int numUniqueEmails(String[] emails) { - Set set = new HashSet<>(); - for (String email : emails) { - set.add(formattedEmail(email)); - } - return set.size(); + return Arrays.stream(emails).map(Solution::getFormattedEmail).collect(Collectors.toSet()).size(); } - - private String formattedEmail(String s) { - StringBuilder sb = new StringBuilder(); - int i = 0; - int n = s.length(); - boolean plusFound = false; - while (i < n) { - char c = s.charAt(i); - if (c == '@') { - break; - } - if (plusFound) { - i++; - continue; - } - else if (c == '+') { - plusFound = true; - } - else if (c != '.') { - sb.append(c); - } - i++; - } - while (i < n) { - sb.append(s.charAt(i++)); - } - return sb.toString(); + + private static String getFormattedEmail(String email) { + String[] strs = email.split("@"); + int plusIdx = strs[0].indexOf('+'); + String formattedLocalName = strs[0].substring(0, (plusIdx == -1 ? strs[0].length() : plusIdx)) + .replaceAll("\\.", ""); + return formattedLocalName + "@" + strs[1]; } } diff --git a/Easy/Unique Morse Code Words.java b/Easy/Unique Morse Code Words.java index 2db49a03..891a02b0 100644 --- a/Easy/Unique Morse Code Words.java +++ b/Easy/Unique Morse Code Words.java @@ -1,17 +1,14 @@ class Solution { + private final String[] CODE = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."}; public int uniqueMorseRepresentations(String[] words) { - String[] morseCodes = { - ".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-", - ".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.." - }; - Set set = new HashSet<>(); - for (String word : words) { - StringBuilder sb = new StringBuilder(); - for (char c : word.toCharArray()) { - sb.append(morseCodes[c - 'a']); - } - set.add(sb.toString()); + return Arrays.stream(words).map(e -> getEncoding(e)).collect(Collectors.toSet()).size(); + } + + private String getEncoding(String s) { + StringBuilder sb = new StringBuilder(); + for (char c : s.toCharArray()) { + sb.append(CODE[c - 'a']); } - return set.size(); + return sb.toString(); } } diff --git a/Easy/Unique Number of Occurrences.java b/Easy/Unique Number of Occurrences.java index fb61d166..b442d51c 100644 --- a/Easy/Unique Number of Occurrences.java +++ b/Easy/Unique Number of Occurrences.java @@ -1,10 +1,9 @@ class Solution { - public boolean uniqueOccurrences(int[] arr) { - Map map = new HashMap<>(); - for (int num : arr) { - map.put(num, map.getOrDefault(num, 0) + 1); - } - Set set = new HashSet<>(map.values()); - return map.size() == set.size(); + public boolean uniqueOccurrences(int[] arr) { + Map map = new HashMap<>(); + for (int num : arr) { + map.put(num, map.getOrDefault(num, 0) + 1); } + return map.size() == new HashSet<>(map.values()).size(); + } } diff --git a/Easy/Valid Palindrome II.java b/Easy/Valid Palindrome II.java index f525f8ce..04a163a0 100644 --- a/Easy/Valid Palindrome II.java +++ b/Easy/Valid Palindrome II.java @@ -1,27 +1,22 @@ class Solution { public boolean validPalindrome(String s) { - int start = 0; - int end = s.length() - 1; - while (start < end && s.charAt(start) == s.charAt(end)) { - start++; - end--; - } - if (start >= end) { - return true; - } - if (isPalindrome(s.substring(start + 1, end + 1)) || isPalindrome(s.substring(start, end))) { - return true; - } - return false; + return validPalindromeHelper(s, false); } - private boolean isPalindrome(String s) { - int start = 0; - int end = s.length() - 1; - while (start < end && s.charAt(start) == s.charAt(end)) { - start++; - end--; + private boolean validPalindromeHelper(String s, boolean deleted) { + int startIdx = 0; + int endIdx = s.length() - 1; + while (startIdx < endIdx) { + if (s.charAt(startIdx) != s.charAt(endIdx)) { + if (deleted) { + return false; + } + return validPalindromeHelper(s.substring(0, startIdx) + s.substring(startIdx + 1), true) || + validPalindromeHelper(s.substring(0, endIdx) + s.substring(endIdx + 1), true); + } + startIdx++; + endIdx--; } - return start >= end; + return true; } } diff --git a/Easy/Valid Palindrome.java b/Easy/Valid Palindrome.java index 255d45ee..efc7bd93 100644 --- a/Easy/Valid Palindrome.java +++ b/Easy/Valid Palindrome.java @@ -1,26 +1,34 @@ class Solution { public boolean isPalindrome(String s) { - int start = 0; - int end = s.length() - 1; - while (start < end) { - if (Character.isLetterOrDigit(s.charAt(start)) && Character.isLetterOrDigit(s.charAt(end))) { - char c1 = Character.isLetter(s.charAt(start)) ? Character.toLowerCase(s.charAt(start)) : s.charAt(start); - char c2 = Character.isLetter(s.charAt(end)) ? Character.toLowerCase(s.charAt(end)) : s.charAt(end); - if (c1 != c2) { + int startIdx = 0; + int endIdx = s.length() - 1; + while (startIdx < endIdx) { + if (!isAlphanumeric(s.charAt(startIdx))) { + startIdx++; + } else if (!isAlphanumeric(s.charAt(endIdx))) { + endIdx--; + } else { + if (!areSame(s.charAt(startIdx), s.charAt(endIdx))) { return false; } - start++; - end--; - } - else { - if (!Character.isLetterOrDigit(s.charAt(start))) { - start++; - } - if (!Character.isLetterOrDigit(s.charAt(end))) { - end--; - } + startIdx++; + endIdx--; } } return true; } + + private boolean areSame(char c1, char c2) { + if (Character.isAlphabetic(c1) && Character.isAlphabetic(c2)) { + return Character.toLowerCase(c1) == Character.toLowerCase(c2); + } else if (Character.isDigit(c1) && Character.isDigit(c2)) { + return c1 == c2; + } else { + return false; + } + } + + private boolean isAlphanumeric(char c) { + return Character.isAlphabetic(c) || Character.isDigit(c); + } } diff --git a/Easy/Valid Parantheses.java b/Easy/Valid Parantheses.java deleted file mode 100644 index 4f6d95b3..00000000 --- a/Easy/Valid Parantheses.java +++ /dev/null @@ -1,26 +0,0 @@ -class Solution { - public boolean isValid(String s) { - Stack stack = new Stack<>(); - String closing = ")}]"; - String opening = "({["; - - for (char c : s.toCharArray()) { - if (closing.indexOf(c) == -1) { - stack.push(c); - } - else { - if (stack.isEmpty()) { - System.out.println("HERE"); - return false; - } - char temp = stack.pop(); - if (opening.indexOf(temp) != closing.indexOf(c)) { - System.out.println(opening.indexOf(temp) + " " + closing.indexOf(c)); - return false; - } - } - } - System.out.println(stack); - return stack.isEmpty(); - } -} diff --git a/Easy/Valid Parentheses.java b/Easy/Valid Parentheses.java new file mode 100644 index 00000000..da0a68f1 --- /dev/null +++ b/Easy/Valid Parentheses.java @@ -0,0 +1,19 @@ +class Solution { + public boolean isValid(String s) { + Deque stack = new ArrayDeque<>(); + for (char c : s.toCharArray()) { + if (c == '(' || c == '[' || c == '{') { + stack.add(c); + } else { + if (stack.isEmpty()) { + return false; + } + char popped = stack.removeLast(); + if (!((c == ')' && popped == '(') || (c == ']' && popped == '[') || (c == '}' && popped == '{'))) { + return false; + } + } + } + return stack.isEmpty(); + } +} diff --git a/Easy/Valid Perfect Square.java b/Easy/Valid Perfect Square.java index ec870dd1..16c1a509 100644 --- a/Easy/Valid Perfect Square.java +++ b/Easy/Valid Perfect Square.java @@ -1,22 +1,22 @@ class Solution { public boolean isPerfectSquare(int num) { - return binarySearchHelper((long)1, (long)num, num) == -1 ? false : true; - } - - private int binarySearchHelper(long start, long end, int num) { + if (num == 1) { + return true; + } + long start = 2; + long end = num / 2; while (start <= end) { - long mid = (start + end) / 2; - long square = (long) Math.pow(mid, 2); - if (square == num) { - return (int) mid; + long mid = start + (end - start) / 2; + long currSquare = mid * mid; + if (currSquare == num) { + return true; } - else if (square > num) { + if (currSquare > num) { end = mid - 1; - } - else { + } else { start = mid + 1; } } - return -1; + return false; } } diff --git a/Easy/Valid Word Abbrevation.java b/Easy/Valid Word Abbrevation.java deleted file mode 100644 index 4299405e..00000000 --- a/Easy/Valid Word Abbrevation.java +++ /dev/null @@ -1,26 +0,0 @@ -class Solution { - public boolean validWordAbbreviation(String word, String abbr) { - int idx1 = 0; - int idx2 = 0; - while (idx1 < word.length() && idx2 < abbr.length()) { - if (!Character.isDigit(abbr.charAt(idx2))) { - if (word.charAt(idx1) != abbr.charAt(idx2)) { - return false; - } - idx1++; - idx2++; - } - else { - if (abbr.charAt(idx2) == '0') { - return false; - } - int count = 0; - while (idx2 < abbr.length() && Character.isDigit(abbr.charAt(idx2))) { - count = count * 10 + Character.getNumericValue(abbr.charAt(idx2++)); - } - idx1 += count; - } - } - return idx1 == word.length() && idx2 == abbr.length(); - } -} diff --git a/Easy/Valid Word Abbreviation.java b/Easy/Valid Word Abbreviation.java new file mode 100644 index 00000000..688b39fe --- /dev/null +++ b/Easy/Valid Word Abbreviation.java @@ -0,0 +1,28 @@ +class Solution { + public boolean validWordAbbreviation(String word, String abbr) { + int wordIdx = 0; + int abbrIdx = 0; + while (wordIdx < word.length() && abbrIdx < abbr.length()) { + if (Character.isDigit(abbr.charAt(abbrIdx))) { + if (abbr.charAt(abbrIdx) == '0') { + return false; + } + int count = 0; + while (abbrIdx < abbr.length() && Character.isDigit(abbr.charAt(abbrIdx))) { + count = count * 10 + Character.getNumericValue(abbr.charAt(abbrIdx++)); + } + wordIdx += count; + if (wordIdx > word.length()) { + return false; + } + } else { + if (word.charAt(wordIdx) != abbr.charAt(abbrIdx)) { + return false; + } + wordIdx++; + abbrIdx++; + } + } + return wordIdx == word.length() && abbrIdx == abbr.length(); + } +} diff --git a/Easy/Valid Word Square.java b/Easy/Valid Word Square.java new file mode 100644 index 00000000..0226d4d5 --- /dev/null +++ b/Easy/Valid Word Square.java @@ -0,0 +1,23 @@ +class Solution { + public boolean validWordSquare(List words) { + int column = 0; + for (String rowWord : words) { + String columnWord = getColumnWord(words, column++); + if (!rowWord.equals(columnWord)) { + return false; + } + } + return true; + } + + private String getColumnWord(List words, int column) { + StringBuilder sb = new StringBuilder(); + for (String word : words) { + if (column >= word.length()) { + break; + } + sb.append(word.charAt(column)); + } + return sb.toString(); + } +} diff --git a/Easy/Valid Word.java b/Easy/Valid Word.java new file mode 100644 index 00000000..c9611bbd --- /dev/null +++ b/Easy/Valid Word.java @@ -0,0 +1,21 @@ +class Solution { + + private static final Set VOWELS = Set.of('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'); + + public boolean isValid(String word) { + boolean vowelFound = false; + boolean consonantFound = false; + for (char c : word.toCharArray()) { + if (Character.isLetter(c)) { + if (VOWELS.contains(c)) { + vowelFound = true; + } else { + consonantFound = true; + } + } else if (!Character.isDigit(c)) { + return false; + } + } + return word.length() >= 3 && vowelFound && consonantFound; + } +} diff --git a/Easy/Verifying an Alien Dictionary.java b/Easy/Verifying an Alien Dictionary.java index ceccf55b..08bf111e 100644 --- a/Easy/Verifying an Alien Dictionary.java +++ b/Easy/Verifying an Alien Dictionary.java @@ -1,30 +1,27 @@ class Solution { - public boolean isAlienSorted(String[] words, String order) { - Map map = new HashMap<>(); - for (int i = 0; i < order.length(); i++) { - map.put(order.charAt(i), i); - } - for (int i = 0; i < words.length - 1; i++) { - if (!verifyHelper(words[i], words[i + 1], map)) { - return false; - } - } - return true; - } - - private boolean verifyHelper(String s1, String s2, Map map) { - int idx1 = 0; - int idx2 = 0; - while (idx1 < s1.length() && idx2 < s2.length()) { - if (map.get(s1.charAt(idx1)) < map.get(s2.charAt(idx2))) { + public boolean isAlienSorted(String[] words, String order) { + Map map = new HashMap<>(); + for (int i = 0; i < order.length(); i++) { + map.put(order.charAt(i), i); + } + for (int i = 0; i < words.length - 1; i++) { + if (!inOrder(words[i], words[i + 1], map)) { + return false; + } + } return true; - } - if (map.get(s1.charAt(idx1)) > map.get(s2.charAt(idx2))) { - return false; - } - idx1++; - idx2++; } - return s1.length() <= s2.length(); - } + + private static boolean inOrder(String wordOne, String wordTwo, Map map) { + for (int i = 0; i < Math.min(wordOne.length(), wordTwo.length()); i++) { + int diff = map.get(wordOne.charAt(i)) - map.get(wordTwo.charAt(i)); + if (diff < 0) { + return true; + } + if (diff > 0) { + return false; + } + } + return wordOne.length() <= wordTwo.length(); + } } diff --git a/Easy/Winner of the Linked List Game.java b/Easy/Winner of the Linked List Game.java new file mode 100644 index 00000000..198fdd75 --- /dev/null +++ b/Easy/Winner of the Linked List Game.java @@ -0,0 +1,23 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public String gameResult(ListNode head) { + ListNode curr = head; + int count = 0; + while (curr != null) { + int even = curr.val; + int odd = curr.next.val; + count += even == odd ? 0 : (even > odd ? 1 : -1); + curr = curr.next.next; + } + return count == 0 ? "Tie" : (count > 0 ? "Even" : "Odd"); + } +} diff --git a/Easy/XOR Operation in an Array.java b/Easy/XOR Operation in an Array.java new file mode 100644 index 00000000..17908959 --- /dev/null +++ b/Easy/XOR Operation in an Array.java @@ -0,0 +1,10 @@ +class Solution { + public int xorOperation(int n, int start) { + int xor = start; + for (int i = 1; i < n; i++) { + int nextNum = start + 2 * i; + xor = xor ^ nextNum; + } + return xor; + } +} diff --git a/Easy/contains_duplicates.java b/Easy/contains_duplicates.java deleted file mode 100644 index e779009b..00000000 --- a/Easy/contains_duplicates.java +++ /dev/null @@ -1,35 +0,0 @@ -import java.util.Arrays; -public class Solution { - public boolean containsDuplicate(int[] nums) { - int n = nums.length; - Arrays.sort(nums); - int c=1; - for(int i=0;i 0) { - profit += diff; - } - } - - return profit; - } -} diff --git a/Explore/Easy/Arrays/Contains Duplicate.java b/Explore/Easy/Arrays/Contains Duplicate.java deleted file mode 100644 index 4268a04d..00000000 --- a/Explore/Easy/Arrays/Contains Duplicate.java +++ /dev/null @@ -1,11 +0,0 @@ -class Solution { - public boolean containsDuplicate(int[] nums) { - Set arr = new HashSet<>(); - - for (int i=0;i map1 = new HashMap<>(); - Map map2 = new HashMap<>(); - - for (int i=0;i list = new ArrayList<>(); - - for(Map.Entry entry : map1.entrySet()) { - if (map2.containsKey(entry.getKey())) { - int count = Math.min(entry.getValue(), map2.get(entry.getKey())); - while (count > 0) { - list.add(entry.getKey()); - count--; - } - } - } - - int[] ans = new int[list.size()]; - - for (int i=0;i=0;i--) { - if (digits[i] < 9) { - digits[i]++; - return digits; - } - - digits[i] = 0; - } - - int[] newDigits = new int[digits.length+1]; - newDigits[0] = 1; - - return newDigits; - } -} diff --git a/Explore/Easy/Arrays/Remove Duplicates from Sorted Array.java b/Explore/Easy/Arrays/Remove Duplicates from Sorted Array.java deleted file mode 100644 index 7f1b92d8..00000000 --- a/Explore/Easy/Arrays/Remove Duplicates from Sorted Array.java +++ /dev/null @@ -1,19 +0,0 @@ -class Solution { - public int removeDuplicates(int[] nums) { - int n = nums.length; - - if (n == 0 || n == 1) return n; - - int j = 0; - - for (int i=0;i map = new HashMap<>(); - int[] ans = new int[2]; - - for (int i=0;i rows = new HashSet(); - Set columns = new HashSet(); - Set cube = new HashSet(); - - for (int j = 0; j < 9;j++) { - - if(board[i][j]!='.' && !rows.add(board[i][j])) - return false; - - if(board[j][i]!='.' && !columns.add(board[j][i])) - return false; - - int RowIndex = 3*(i/3); - int ColIndex = 3*(i%3); - - if(board[RowIndex + j/3][ColIndex + j%3]!='.' && !cube.add(board[RowIndex + j/3][ColIndex + j%3])) - return false; - } - - } - - return true; - } -} diff --git a/Explore/Easy/Design/Min Stack.java b/Explore/Easy/Design/Min Stack.java deleted file mode 100644 index 41c7c6ed..00000000 --- a/Explore/Easy/Design/Min Stack.java +++ /dev/null @@ -1,42 +0,0 @@ -class MinStack { - private Stack stack = new Stack(); - private Stack minStack = new Stack(); - - public void push(int x) { - stack.push(x); - if (minStack.size() != 0) { - int min = minStack.peek(); - if (x <= min) { - minStack.push(x); - } - } else { - minStack.push(x); - } - } - - public void pop() { - int x = stack.pop(); - if (minStack.size() != 0) { - if (x == minStack.peek()) { - minStack.pop(); - } - } - } - - public int top() { - return stack.peek(); - } - - public int getMin() { - return minStack.peek(); - } -} - -/** - * Your MinStack object will be instantiated and called as such: - * MinStack obj = new MinStack(); - * obj.push(x); - * obj.pop(); - * int param_3 = obj.top(); - * int param_4 = obj.getMin(); - */ diff --git a/Explore/Easy/Design/Shuffle an Array.java b/Explore/Easy/Design/Shuffle an Array.java deleted file mode 100644 index 05fc1174..00000000 --- a/Explore/Easy/Design/Shuffle an Array.java +++ /dev/null @@ -1,40 +0,0 @@ -class Solution { - - private int[] nums; - private Random random; - - public Solution(int[] nums) { - this.nums = nums; - random = new Random(); - } - - /** Resets the array to its original configuration and return it. */ - public int[] reset() { - return nums; - } - - /** Returns a random shuffling of the array. */ - public int[] shuffle() { - if (nums == null) return null; - int[] shuf = nums.clone(); - for (int i=1;i n) return 0; - if (i == n) return 1; - - if (memo[i] > 0) return memo[i]; - - memo[i] = climbStairs(memo, i+1, n) + climbStairs(memo, i+2, n); - - return memo[i]; - } -} diff --git a/Explore/Easy/Dynamic Programming/House Robber.java b/Explore/Easy/Dynamic Programming/House Robber.java deleted file mode 100644 index 4f5b502c..00000000 --- a/Explore/Easy/Dynamic Programming/House Robber.java +++ /dev/null @@ -1,12 +0,0 @@ -class Solution { - public int rob(int[] nums) { - int[][] dp = new int[nums.length+1][2]; - - for (int i=1;i<=nums.length;i++) { - dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1]); - dp[i][1] = nums[i-1] + dp[i-1][0]; - } - - return Math.max(dp[nums.length][0], dp[nums.length][1]); - } -} diff --git a/Explore/Easy/Dynamic Programming/Maximum Subarray.java b/Explore/Easy/Dynamic Programming/Maximum Subarray.java deleted file mode 100644 index 70fa9505..00000000 --- a/Explore/Easy/Dynamic Programming/Maximum Subarray.java +++ /dev/null @@ -1,22 +0,0 @@ -class Solution { - public int maxSubArray(int[] nums) { - - int sum = 0; - int max = Integer.MIN_VALUE; - int i = 0; - - while (i l2.val) { - temp.next = new ListNode(l2.val); - temp = temp.next; - l2 = l2.next; - } - else { - temp.next = new ListNode(l1.val); - temp = temp.next; - l1 = l1.next; - } - } - else if (l1 != null) { - temp.next = new ListNode(l1.val); - temp = temp.next; - l1 = l1.next; - } - else if (l2 != null) { - temp.next = new ListNode(l2.val); - temp = temp.next; - l2 = l2.next; - } - } - - return ans.next; - } -} diff --git a/Explore/Easy/Linked Lists/Palindrome Linked List.java b/Explore/Easy/Linked Lists/Palindrome Linked List.java deleted file mode 100644 index 2b7a5c25..00000000 --- a/Explore/Easy/Linked Lists/Palindrome Linked List.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode(int x) { val = x; } - * } - */ -class Solution { - public boolean isPalindrome(ListNode head) { - if (head == null || head.next == null) return true; - int l = 0; - ListNode curr = head; - - while (curr != null) { - l++; - curr = curr.next; - } - - int i = 1; - curr = head; - - while (i < l/2) { - curr = curr.next; - i++; - } - - ListNode mid = reverse(curr.next); - - curr = head; - - while(mid != null) { - if (curr.val != mid.val) return false; - curr = curr.next; - mid = mid.next; - } - - return true; - } - - public ListNode reverse(ListNode head) { - ListNode curr = head; - ListNode prev = null; - ListNode next = null; - - while(curr != null) { - next = curr.next; - curr.next = prev; - prev = curr; - curr = next; - } - - return prev; - } -} diff --git a/Explore/Easy/Linked Lists/Remove Nth Node From End of List.java b/Explore/Easy/Linked Lists/Remove Nth Node From End of List.java deleted file mode 100644 index a319e3ec..00000000 --- a/Explore/Easy/Linked Lists/Remove Nth Node From End of List.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode(int x) { val = x; } - * } - */ -class Solution { - public ListNode removeNthFromEnd(ListNode head, int n) { - int l = 0; - ListNode curr = head; - - while (curr != null) { - l++; - curr = curr.next; - } - - if (l -n == 0) { - ListNode tmp = head.next; - head = null; - return tmp; - } - - curr = head; - int c = 1; - l = l-n; - - while(c != l) { - c++; - curr = curr.next; - } - - curr.next = curr.next.next; - - return head; - } -} diff --git a/Explore/Easy/Linked Lists/Reverse Linked List.java b/Explore/Easy/Linked Lists/Reverse Linked List.java deleted file mode 100644 index 8aeaa6ae..00000000 --- a/Explore/Easy/Linked Lists/Reverse Linked List.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode(int x) { val = x; } - * } - */ -class Solution { - public ListNode reverseList(ListNode head) { - ListNode curr = head; - ListNode prev = null; - ListNode next = null; - - while (curr != null) { - next = curr.next; - curr.next = prev; - prev = curr; - curr = next; - } - - return prev; - } -} diff --git a/Explore/Easy/Math/Count Primes.java b/Explore/Easy/Math/Count Primes.java deleted file mode 100644 index cce1c733..00000000 --- a/Explore/Easy/Math/Count Primes.java +++ /dev/null @@ -1,21 +0,0 @@ -class Solution { - public int countPrimes(int n) { - int[] arr = new int[n]; - - for (int i=2;i fizzBuzz(int n) { - List ans = new ArrayList<>(); - for (int i=1;i<=n;i++) { - if (i%3 != 0 && i%5 != 0) { - ans.add(String.valueOf(i)); - } - else if (i%3 == 0 && i%5 == 0) { - ans.add("FizzBuzz"); - } - else if(i%3 == 0) { - ans.add("Fizz"); - } - else { - ans.add("Buzz"); - } - } - - return ans; - } -} diff --git a/Explore/Easy/Math/Power of Three.java b/Explore/Easy/Math/Power of Three.java deleted file mode 100644 index ed03bb74..00000000 --- a/Explore/Easy/Math/Power of Three.java +++ /dev/null @@ -1,11 +0,0 @@ -class Solution { - public boolean isPowerOfThree(int n) { - if (n < 1) return false; - - while (n%3 == 0) { - n /= 3; - } - - return n == 1; - } -} diff --git a/Explore/Easy/Math/Roman to Integer.java b/Explore/Easy/Math/Roman to Integer.java deleted file mode 100644 index 2078e1d5..00000000 --- a/Explore/Easy/Math/Roman to Integer.java +++ /dev/null @@ -1,39 +0,0 @@ -class Solution { - public int romanToInt(String s) { - String symbol = "IVXLCDM"; - int[] val = {1, 5, 10, 50, 100, 500, 1000}; - - char[] s_char = s.toCharArray(); - - int[] s_val = new int[s_char.length]; - - for (int i=0;i= s2) { - total += s1; - k++; - } - else{ - total += s2-s1; - k += 2; - } - } - else { - total += s1; - k++; - } - } - - return total; - } -} diff --git a/Explore/Easy/Others/Hamming Distance.java b/Explore/Easy/Others/Hamming Distance.java deleted file mode 100644 index 057a1b25..00000000 --- a/Explore/Easy/Others/Hamming Distance.java +++ /dev/null @@ -1,5 +0,0 @@ -class Solution { - public int hammingDistance(int x, int y) { - return Integer.bitCount(x^y); - } -} diff --git a/Explore/Easy/Others/Missing Number.java b/Explore/Easy/Others/Missing Number.java deleted file mode 100644 index c9886640..00000000 --- a/Explore/Easy/Others/Missing Number.java +++ /dev/null @@ -1,11 +0,0 @@ -class Solution { - public int missingNumber(int[] nums) { - int xor = 0; - int i = 0; - for (i=0;i map = new HashMap<>(); - public List> generate(int numRows) { - List> ans = new ArrayList<>(); - - for (int i=0;i temp = new ArrayList<>(); - for(int j = 0;j<=i;j++) { - if (i == j || j == 0) { - temp.add(1); - } - else { - temp.add(ans.get(i-1).get(j-1) + ans.get(i-1).get(j)); - } - } - - ans.add(temp); - } - - return ans; - } -} diff --git a/Explore/Easy/Others/Reverse Bits.java b/Explore/Easy/Others/Reverse Bits.java deleted file mode 100644 index 36ec5763..00000000 --- a/Explore/Easy/Others/Reverse Bits.java +++ /dev/null @@ -1,13 +0,0 @@ -public class Solution { - // you need treat n as an unsigned value - public int reverseBits(int n) { - int result = 0; - for (int i = 0; i < 32; i++) { - result += n & 1; - n >>>= 1; - if (i < 31) - result <<= 1; - } - return result; - } -} diff --git a/Explore/Easy/Others/Valid Parantheses.java b/Explore/Easy/Others/Valid Parantheses.java deleted file mode 100644 index 10033b6a..00000000 --- a/Explore/Easy/Others/Valid Parantheses.java +++ /dev/null @@ -1,23 +0,0 @@ -class Solution { - public boolean isValid(String s) { - String start = "({["; - String end = ")}]"; - - Stack stack = new Stack<>(); - - for (int i=0;i=0 && j>=0) { - if (nums1[i] > nums2[j]) { - nums1[k--] = nums1[i--]; - } - else { - nums1[k--] = nums2[j--]; - } - } - - while(j >= 0) { - nums1[k--] = nums2[j--]; - } - } -} diff --git a/Explore/Easy/Strings/Count and Say.java b/Explore/Easy/Strings/Count and Say.java deleted file mode 100644 index 8fd83c74..00000000 --- a/Explore/Easy/Strings/Count and Say.java +++ /dev/null @@ -1,32 +0,0 @@ -class Solution { - public String countAndSay(int n) { - String first = "1"; - String str = "11"; - - if (n == 1) return first; - if (n == 2) return str; - - for (int i = 3; i<=n; i++) { - str += "$"; - int len = str.length(); - - int cnt = 1; - String tmp = ""; - - for (int j = 1; j < len; j++) { - if (str.charAt(j) != str.charAt(j-1)) { - tmp += String.valueOf(cnt); - tmp += str.charAt(j-1); - - cnt = 1; - } - - else cnt++; - } - - str = tmp; - } - - return str; - } -} diff --git a/Explore/Easy/Strings/First Unique Character in a String.java b/Explore/Easy/Strings/First Unique Character in a String.java deleted file mode 100644 index 5c20c16d..00000000 --- a/Explore/Easy/Strings/First Unique Character in a String.java +++ /dev/null @@ -1,17 +0,0 @@ -class Solution { - public int firstUniqChar(String s) { - int[] ascii = new int[26]; - - for (int i=0;i= '0' && c[i] <= '9') { - int digit = c[i] - '0'; - if (num > bound || (num == bound && digit > 7)) { - return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; - } - - num = num * 10 + digit; - i++; - } - return sign * num; - } -} diff --git a/Explore/Easy/Strings/Valid Anagram.java b/Explore/Easy/Strings/Valid Anagram.java deleted file mode 100644 index aaa0953a..00000000 --- a/Explore/Easy/Strings/Valid Anagram.java +++ /dev/null @@ -1,22 +0,0 @@ -class Solution { - public boolean isAnagram(String s, String t) { - - if (s.length() != t.length()) return false; - - int[] ascii = new int[26]; - - for (int i=0;i= 97 && (int) s.charAt(i) <= 122) || Character.isDigit(s.charAt(i))) { - sb.append(String.valueOf(s.charAt(i))); - } - } - - return sb.toString().toLowerCase().equals(sb.reverse().toString().toLowerCase()); - } -} diff --git a/Explore/Easy/Trees/Binary Tree Level Order Traversal.java b/Explore/Easy/Trees/Binary Tree Level Order Traversal.java deleted file mode 100644 index c1323496..00000000 --- a/Explore/Easy/Trees/Binary Tree Level Order Traversal.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public List> levelOrder(TreeNode root) { - Queue queue = new LinkedList<>(); - List> ans = new ArrayList<>(); - - if (root == null) return ans; - - queue.add(root); - - while(!queue.isEmpty()) { - List temp = new ArrayList<>(); - while (!queue.isEmpty()) { - temp.add(queue.remove()); - } - - List lst = new ArrayList<>(); - - for (TreeNode t : temp) { - lst.add(t.val); - - if (t.left != null) queue.add(t.left); - if (t.right != null) queue.add(t.right); - } - - ans.add(lst); - } - - return ans; - } -} diff --git a/Explore/Easy/Trees/Convert Sorted Array to Binary Search Tree.java b/Explore/Easy/Trees/Convert Sorted Array to Binary Search Tree.java deleted file mode 100644 index 92393eda..00000000 --- a/Explore/Easy/Trees/Convert Sorted Array to Binary Search Tree.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public TreeNode sortedArrayToBST(int[] nums) { - return sortedArrayToBST(nums, 0, nums.length-1); - } - - public TreeNode sortedArrayToBST(int arr[], int start, int end) { - - if (start > end) { - return null; - } - - int mid = (start + end) / 2; - - TreeNode node = new TreeNode(arr[mid]); - node.left = sortedArrayToBST(arr, start, mid - 1); - node.right = sortedArrayToBST(arr, mid + 1, end); - - return node; - } -} diff --git a/Explore/Easy/Trees/Maximum Depth of Binary Tree.java b/Explore/Easy/Trees/Maximum Depth of Binary Tree.java deleted file mode 100644 index 8dc92307..00000000 --- a/Explore/Easy/Trees/Maximum Depth of Binary Tree.java +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public int maxDepth(TreeNode root) { - if (root == null) return 0; - - return 1 + Math.max(maxDepth(root.left), maxDepth(root.right)); - } -} diff --git a/Explore/Easy/Trees/Symmetric Tree.java b/Explore/Easy/Trees/Symmetric Tree.java deleted file mode 100644 index 65a6d838..00000000 --- a/Explore/Easy/Trees/Symmetric Tree.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public boolean isSymmetric(TreeNode root) { - if (root == null) return true; - - return isSymmetric(root.left, root.right); - } - - public boolean isSymmetric(TreeNode rLeft, TreeNode rRight) { - if (rLeft == null && rRight == null) { - return true; - } - if ((rLeft == null && rRight != null) || (rLeft != null && rRight == null)) { - return false; - } - - if (rLeft != null && rRight != null) { - if (rLeft.val != rRight.val) return false; - } - - return isSymmetric(rLeft.left, rRight.right) && isSymmetric(rLeft.right, rRight.left); - } -} diff --git a/Explore/Easy/Trees/Validate Binary Search Tree.java b/Explore/Easy/Trees/Validate Binary Search Tree.java deleted file mode 100644 index ad07834a..00000000 --- a/Explore/Easy/Trees/Validate Binary Search Tree.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public boolean isValidBST(TreeNode root) { - Stack stack = new Stack<>(); - TreeNode prev = null; - - while (root != null || !stack.empty()) { - while(root != null) { - stack.push(root); - root = root.left; - } - - if (prev != null && prev.val >= stack.peek().val) { - return false; - } - - root = stack.pop(); - prev = root; - root = root.right; - } - - return true; - } -} diff --git a/Explore/Medium/Arrays and Strings/3Sum.java b/Explore/Medium/Arrays and Strings/3Sum.java deleted file mode 100644 index fa68d8bb..00000000 --- a/Explore/Medium/Arrays and Strings/3Sum.java +++ /dev/null @@ -1,34 +0,0 @@ -class Solution { - public List> threeSum(int[] nums) { - - Arrays.sort(nums); - - List> ans = new ArrayList<>(); - - for (int i=0;i 0 && nums[i] == nums[i-1]) continue; - - int j = i+1; - int k = nums.length-1; - - int target = -nums[i]; - - while (j target) k--; - else { - j++; - } - } - } - - return ans; - } -} diff --git a/Explore/Medium/Arrays and Strings/Group Anagrams.java b/Explore/Medium/Arrays and Strings/Group Anagrams.java deleted file mode 100644 index 758782ae..00000000 --- a/Explore/Medium/Arrays and Strings/Group Anagrams.java +++ /dev/null @@ -1,30 +0,0 @@ -class Solution { - public List> groupAnagrams(String[] strs) { - Map> map = new HashMap<>(); - - for (String s : strs) { - char[] ar = s.toCharArray(); - Arrays.sort(ar); - String s_sorted = String.valueOf(ar); - - if (map.containsKey(s_sorted)) { - List temp = map.get(s_sorted); - temp.add(s); - map.put(s_sorted, temp); - } - else { - List temp = new ArrayList<>(); - temp.add(s); - map.put(s_sorted, temp); - } - } - - List> ans = new ArrayList<>(); - - for (Map.Entry> entry : map.entrySet()) { - ans.add(entry.getValue()); - } - - return ans; - } -} diff --git a/Explore/Medium/Arrays and Strings/Increasing Triplet Subsequence.java b/Explore/Medium/Arrays and Strings/Increasing Triplet Subsequence.java deleted file mode 100644 index b90490c6..00000000 --- a/Explore/Medium/Arrays and Strings/Increasing Triplet Subsequence.java +++ /dev/null @@ -1,21 +0,0 @@ -class Solution { - public boolean increasingTriplet(int[] nums) { - if (nums.length < 3) return false; - - int x = Integer.MAX_VALUE; - int y = Integer.MAX_VALUE; - - for (int i=0;i= z) { - x = z; - } - else if (y >= z) { - y = z; - } - else return true; - } - - return false; - } -} diff --git a/Explore/Medium/Arrays and Strings/Longest Palindromic Substring.java b/Explore/Medium/Arrays and Strings/Longest Palindromic Substring.java deleted file mode 100644 index 569508e3..00000000 --- a/Explore/Medium/Arrays and Strings/Longest Palindromic Substring.java +++ /dev/null @@ -1,28 +0,0 @@ -class Solution { - public String longestPalindrome(String s) { - int start = 0; - int end = 0; - - for (int i=0;i end - start) { - start = i - (len - 1)/2; - end = i + len/2; - } - } - - return s.substring(start, end+1); - } - - public int expandCenter(String s, int left, int right) { - while (left >=0 && right < s.length() && s.charAt(left) == s.charAt(right)) { - left--; - right++; - } - - return right - left - 1; - } -} diff --git a/Explore/Medium/Arrays and Strings/Longest Substring Without Repeating Characters.java b/Explore/Medium/Arrays and Strings/Longest Substring Without Repeating Characters.java deleted file mode 100644 index bde380e6..00000000 --- a/Explore/Medium/Arrays and Strings/Longest Substring Without Repeating Characters.java +++ /dev/null @@ -1,22 +0,0 @@ -class Solution { - public int lengthOfLongestSubstring(String s) { - - Set set = new HashSet<>(); - int maxLen = Integer.MIN_VALUE; - - int i=0, j=0; - int n = s.length(); - - while(i findMissingRanges(int[] nums, int lower, int upper) { - List list = new ArrayList<>(); - - if (nums.length == 0) { - list.add(getString(lower, upper)); - return list; - } - - List range = getRange(nums); - int i = 0; - - while (lower <= upper && i < range.size()) { - String s = range.get(i); - if (s.indexOf('>') != -1) { - int start = Integer.parseInt(s.split("->")[0]); - int end = Integer.parseInt(s.split("->")[1]); - - if (lower != start) { - list.add(getString(lower, start-1)); - } - - lower = end + 1; - } - else { - int num = Integer.parseInt(s); - if (lower != num) { - list.add(getString(lower, num-1)); - } - - lower = num + 1; - } - - i++; - } - - String s = range.get(range.size()-1); - if (s.indexOf('>') != -1) { - int start = Integer.parseInt(s.split("->")[0]); - int end = Integer.parseInt(s.split("->")[1]); - - if (end != upper) { - list.add(getString(end+1, upper)); - } - } - else { - int num = Integer.parseInt(s); - if (upper != num) { - list.add(getString(num+1, upper)); - } - } - - return list; - } - - private static List getRange(int[] num) { - - List list = new ArrayList<>(); - if (num.length == 0) { - return list; - } - - int i = 1; - StringBuilder sb = new StringBuilder(); - sb.append(num[0]); - int count = 1; - - while (i 1) { - sb.append("->").append(num[i-1]); - list.add(sb.toString()); - } - else { - list.add(sb.toString()); - } - - sb = new StringBuilder(); - sb.append(num[i]); - count = 1; - } - - i++; - } - - if (count > 1) { - sb.append("->").append(num[num.length-1]); - } - - list.add(sb.toString()); - - return list; - } - - private static String getString(int start, int end) { - StringBuilder sb = new StringBuilder(); - if (start == end) { - sb.append(start); - } - else { - sb.append(start).append("->").append(end); - } - - return sb.toString(); - } -} diff --git a/Explore/Medium/Arrays and Strings/Set Matrix Zeroes.java b/Explore/Medium/Arrays and Strings/Set Matrix Zeroes.java deleted file mode 100644 index 6c043646..00000000 --- a/Explore/Medium/Arrays and Strings/Set Matrix Zeroes.java +++ /dev/null @@ -1,64 +0,0 @@ -class Solution { - public void setZeroes(int[][] arr) { - if (arr.length == 0 || arr[0].length == 0) { - return; - } - - - int numOfRows = arr.length; - int numOfCols = arr[0].length; - boolean firstRowZero = false; - boolean firstColZero = false; - - for (int i = 0; i < numOfCols; i++) { - if (arr[0][i] == 0) { - firstRowZero = true; - break; - } - } - - for (int i = 0; i < numOfRows; i++) { - if (arr[i][0] == 0) { - firstColZero = true; - break; - } - } - - for (int i = 1; i < numOfRows; i++) { - for (int j = 0; j < numOfCols; j++) { - if (arr[i][j] == 0) { - arr[0][j] = 0; - arr[i][0] = 0; - } - } - } - - for (int i = 1; i < numOfRows; i++) { - if (arr[i][0] == 0) { - for (int j = 1; j < numOfCols; j++) { - arr[i][j] = 0; - } - } - } - - for (int i = 0; i < numOfCols; i++) { - if (arr[0][i] == 0) { - for (int j = 1; j < numOfRows; j++) { - arr[j][i] = 0; - } - } - } - - if (firstRowZero) { - for (int i = 0; i < numOfCols; i++) { - arr[0][i] = 0; - } - } - - if (firstColZero) { - for (int i = 0; i < numOfRows; i++) { - arr[i][0] = 0; - } - } - } -} diff --git a/Explore/Medium/Linked Lists/Add Two Numbers.java b/Explore/Medium/Linked Lists/Add Two Numbers.java deleted file mode 100644 index 5ec675ce..00000000 --- a/Explore/Medium/Linked Lists/Add Two Numbers.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode(int x) { val = x; } - * } - */ -class Solution { - public ListNode addTwoNumbers(ListNode l1, ListNode l2) { - ListNode ans = new ListNode(0); - ListNode curr = ans; - - int carry = 0; - - while (l1 != null || l2 != null) { - - int temp = 0; - - if (l1 != null && l2 != null) { - temp = l1.val + l2.val + carry; - l1 = l1.next; - l2 = l2.next; - } - else if (l1 != null && l2 == null) { - temp = l1.val + carry; - l1 = l1.next; - } - else if (l1 == null && l2 != null) { - temp = l2.val + carry; - l2 = l2.next; - } - - carry = temp > 9 ? temp/10 : 0; - temp = temp > 9 ? temp%10 : temp; - - curr.next = new ListNode(temp); - curr = curr.next; - } - - if (carry != 0) { - curr.next = new ListNode(carry); - curr = curr.next; - } - - return ans.next; - } -} diff --git a/Explore/Medium/Linked Lists/Intersection of Two Linked Lists.java b/Explore/Medium/Linked Lists/Intersection of Two Linked Lists.java deleted file mode 100644 index 316eefbe..00000000 --- a/Explore/Medium/Linked Lists/Intersection of Two Linked Lists.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode(int x) { - * val = x; - * next = null; - * } - * } - */ -public class Solution { - public ListNode getIntersectionNode(ListNode headA, ListNode headB) { - - if (headA == null || headB == null) return null; - - int lenA = getLength(headA); - int lenB = getLength(headB); - - ListNode currA = headA; - ListNode currB = headB; - - if (lenB > lenA) { - int diff = lenB - lenA; - - while (diff != 0) { - currB = currB.next; - diff--; - } - } - else { - int diff = lenA - lenB; - - while (diff != 0) { - currA = currA.next; - diff--; - } - } - - while(currB != null) { - if (currA == currB) return currA; - currA = currA.next; - currB = currB.next; - } - - return null; - } - - public int getLength(ListNode head) { - int l = 0; - while (head != null) { - head = head.next; - l++; - } - - return l; - } -} diff --git a/Explore/Medium/Linked Lists/Odd Even Linked List.java b/Explore/Medium/Linked Lists/Odd Even Linked List.java deleted file mode 100644 index 92b55544..00000000 --- a/Explore/Medium/Linked Lists/Odd Even Linked List.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode(int x) { val = x; } - * } - */ -class Solution { - public ListNode oddEvenList(ListNode head) { - - if (head == null || head.next == null) return head; - - ListNode odd = head; - ListNode even = head.next; - ListNode evenHead = even; - - while(even != null && even.next != null) { - odd.next = odd.next.next; - even.next = even.next.next; - - odd = odd.next; - even = even.next; - } - - odd.next = evenHead; - - return head; - } -} diff --git a/Explore/Medium/Sorting & Searching/Sort Colors.java b/Explore/Medium/Sorting & Searching/Sort Colors.java deleted file mode 100644 index 4a8fdd4e..00000000 --- a/Explore/Medium/Sorting & Searching/Sort Colors.java +++ /dev/null @@ -1,23 +0,0 @@ -class Solution { - public void sortColors(int[] nums) { - - int n0 = -1; - int n1 = -1; - int n2 = -1; - - for (int i=0;i topKFrequent(int[] nums, int k) { - List[] bucket = new List[nums.length+1]; - Map frequencyMap = new HashMap<>(); - for (int n : nums) { - frequencyMap.put(n, frequencyMap.getOrDefault(n, 0) + 1); - } - - for (int key : frequencyMap.keySet()) { - int frequency = frequencyMap.get(key); - - if (bucket[frequency] == null) { - bucket[frequency] = new ArrayList<>(); - } - - bucket[frequency].add(key); - } - - List res = new ArrayList<>(); - - for (int pos = bucket.length - 1; pos >= 0 && res.size() < k; pos--) { - if (bucket[pos] != null) { - res.addAll(bucket[pos]); - } - } - - return res; - } -} diff --git a/Explore/Medium/Trees and Graphs/Binary Tree Inorder Traversal.java b/Explore/Medium/Trees and Graphs/Binary Tree Inorder Traversal.java deleted file mode 100644 index 811b92e6..00000000 --- a/Explore/Medium/Trees and Graphs/Binary Tree Inorder Traversal.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public List inorderTraversal(TreeNode root) { - List list = new ArrayList<>(); - - Stack stack = new Stack<>(); - - while (root != null || !stack.empty()) { - - while(root != null) { - stack.push(root); - root = root.left; - } - - root = stack.pop(); - - list.add(root.val); - root = root.right; - } - - return list; - } -} diff --git a/Explore/Medium/Trees and Graphs/Binary Tree Zigzag Level Order Traversal.java b/Explore/Medium/Trees and Graphs/Binary Tree Zigzag Level Order Traversal.java deleted file mode 100644 index a87e311c..00000000 --- a/Explore/Medium/Trees and Graphs/Binary Tree Zigzag Level Order Traversal.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public List> zigzagLevelOrder(TreeNode root) { - - Stack s1 = new Stack<>(); - Stack s2 = new Stack<>(); - - List> ans = new ArrayList<>(); - - if (root == null) return ans; - - s1.push(root); - - while (!s1.empty() || !s2.empty()) { - - List list = new ArrayList<>(); - - while (!s1.empty()) { - TreeNode temp = s1.pop(); - - list.add(temp.val); - - if (temp.left != null) { - s2.add(temp.left); - } - - if (temp.right != null) { - s2.add(temp.right); - } - } - - if (list.size() > 0) { - ans.add(list); - continue; - } - - while (!s2.empty()) { - TreeNode temp = s2.pop(); - list.add(temp.val); - - if (temp.right != null) { - s1.add(temp.right); - } - - if (temp.left != null) { - s1.add(temp.left); - } - - } - - ans.add(list); - } - - return ans; - } -} diff --git a/Explore/Medium/Trees and Graphs/Construct Binary Tree from Preorder and Inorder Traversal.java b/Explore/Medium/Trees and Graphs/Construct Binary Tree from Preorder and Inorder Traversal.java deleted file mode 100644 index ddfa9f42..00000000 --- a/Explore/Medium/Trees and Graphs/Construct Binary Tree from Preorder and Inorder Traversal.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public TreeNode buildTree(int[] preorder, int[] inorder) { - return buildTreeHelper(0, 0, inorder.length-1, preorder, inorder); - } - - public TreeNode buildTreeHelper(int preStart, int inStart, int inEnd, int[] preorder, int[] inorder) { - if (preStart > preorder.length-1 || inStart > inEnd) { - return null; - } - - TreeNode root = new TreeNode(preorder[preStart]); - int inIndex = -1; - - for (int i = inStart; i <= inEnd; i++) { - if (inorder[i] == root.val) { - inIndex = i; - break; - } - } - - root.left = buildTreeHelper(preStart+1, inStart, inIndex-1, preorder, inorder); - root.right = buildTreeHelper(preStart + inIndex - inStart + 1, inIndex + 1, inEnd, preorder, inorder); - - return root; - } -} \ No newline at end of file diff --git a/Explore/Medium/Trees and Graphs/Kth Smallest Element in a BST.java b/Explore/Medium/Trees and Graphs/Kth Smallest Element in a BST.java deleted file mode 100644 index 6b46a29f..00000000 --- a/Explore/Medium/Trees and Graphs/Kth Smallest Element in a BST.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public int kthSmallest(TreeNode root, int k) { - Stack stack = new Stack<>(); - List list = new ArrayList<>(); - - while(root != null || !stack.empty()) { - while (root != null) { - stack.push(root); - root = root.left; - } - - root = stack.pop(); - list.add(root.val); - root = root.right; - } - - return list.get(k-1); - } -} diff --git a/Explore/Medium/Trees and Graphs/Populating Next Right Pointers in Each Node.java b/Explore/Medium/Trees and Graphs/Populating Next Right Pointers in Each Node.java deleted file mode 100644 index b012ec6b..00000000 --- a/Explore/Medium/Trees and Graphs/Populating Next Right Pointers in Each Node.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Definition for binary tree with next pointer. - * public class TreeLinkNode { - * int val; - * TreeLinkNode left, right, next; - * TreeLinkNode(int x) { val = x; } - * } - */ -public class Solution { - public void connect(TreeLinkNode root) { - - TreeLinkNode start=root; - - while(start!=null){ - - TreeLinkNode cur=start; - - while(cur!=null){ - if(cur.left!=null) cur.left.next=cur.right; - if(cur.right!=null && cur.next!=null) cur.right.next=cur.next.left; - - cur=cur.next; - } - - start=start.left; - } - } -} diff --git a/Hard/Add Edges to Make Degrees of All Nodes Even.java b/Hard/Add Edges to Make Degrees of All Nodes Even.java new file mode 100644 index 00000000..2258af63 --- /dev/null +++ b/Hard/Add Edges to Make Degrees of All Nodes Even.java @@ -0,0 +1,48 @@ +class Solution { + public boolean isPossible(int n, List> edges) { + Map> graph = new HashMap<>(); + for (List edge : edges) { + graph.computeIfAbsent(edge.get(0), k -> new HashSet<>()).add(edge.get(1)); + graph.computeIfAbsent(edge.get(1), k -> new HashSet<>()).add(edge.get(0)); + } + List nodeWithOddEdges = graph.entrySet() + .stream() + .filter(e -> e.getValue().size() % 2 != 0) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + if (nodeWithOddEdges.size() == 0) { + return true; + } + if (nodeWithOddEdges.size() == 2) { + Integer nodeOne = nodeWithOddEdges.get(0); + Integer nodeTwo = nodeWithOddEdges.get(1); + if (!hasEdge(graph, nodeOne, nodeTwo)) { + return true; + } + for (int i = 1; i <= n; i++) { + if (i == nodeOne || i == nodeTwo) { + continue; + } + if (!hasEdge(graph, i, nodeOne) && !hasEdge(graph, i, nodeTwo)) { + return true; + } + } + } + if (nodeWithOddEdges.size() == 4) { + Integer nodeOne = nodeWithOddEdges.get(0); + Integer nodeTwo = nodeWithOddEdges.get(1); + Integer nodeThree = nodeWithOddEdges.get(2); + Integer nodeFour = nodeWithOddEdges.get(3); + if ((!hasEdge(graph, nodeOne, nodeTwo) && !hasEdge(graph, nodeThree, nodeFour)) || + (!hasEdge(graph, nodeOne, nodeThree) && !hasEdge(graph, nodeTwo, nodeFour)) || + (!hasEdge(graph, nodeOne, nodeFour) && !hasEdge(graph, nodeTwo, nodeThree))) { + return true; + } + } + return false; + } + + private static boolean hasEdge(Map> graph, int nodeOne, int nodeTwo) { + return graph.getOrDefault(nodeOne, new HashSet<>()).contains(nodeTwo); + } +} diff --git a/Hard/Alien Dictionary.java b/Hard/Alien Dictionary.java new file mode 100644 index 00000000..939de634 --- /dev/null +++ b/Hard/Alien Dictionary.java @@ -0,0 +1,48 @@ +class Solution { + public String alienOrder(String[] words) { + Map> graph = new HashMap<>(); + for (String word : words) { + for (char c : word.toCharArray()) { + graph.computeIfAbsent(c, k -> new HashSet<>()); + } + } + for (int i = 0; i < words.length - 1; i++) { + String word1 = words[i]; + String word2 = words[i + 1]; + int minLength = Math.min(word1.length(), word2.length()); + if (word1.length() > word2.length() && word1.startsWith(word2)) { + return ""; + } + for (int j = 0; j < minLength; j++) { + if (word1.charAt(j) != word2.charAt(j)) { + graph.get(word1.charAt(j)).add(word2.charAt(j)); + break; + } + } + } + StringBuilder sb = new StringBuilder(); + Map visited = new HashMap<>(); + for (Character c : graph.keySet()) { + if (dfs(c, graph, sb, visited)) { + return ""; + } + } + return sb.reverse().toString(); + } + + private boolean dfs(Character c, Map> graph, + StringBuilder sb, Map visited) { + if (visited.containsKey(c)) { + return visited.get(c); + } + visited.put(c, true); + for (Character neighbor : graph.getOrDefault(c, new HashSet<>())) { + if (dfs(neighbor, graph, sb, visited)) { + return true; + } + } + visited.put(c, false); + sb.append(c); + return false; + } +} diff --git a/Hard/All O`one Data Structure.java b/Hard/All O`one Data Structure.java new file mode 100644 index 00000000..211e4f01 --- /dev/null +++ b/Hard/All O`one Data Structure.java @@ -0,0 +1,108 @@ +class AllOne { + private final NodeList head; + private final NodeList tail; + private final Map countToNodeMapping; + private final Map keyToCountMapping; + + public AllOne() { + head = new NodeList(Integer.MIN_VALUE); + tail = new NodeList(Integer.MAX_VALUE); + head.next = tail; + tail.prev = head; + countToNodeMapping = new HashMap<>(); + keyToCountMapping = new HashMap<>(); + } + + public void inc(String key) { + if (keyToCountMapping.containsKey(key)) { + updateKey(key, 1); + } else { + keyToCountMapping.put(key, 1); + if (head.next.count != 1) { + addNodeAfter(new NodeList(1), head); + } + head.next.keys.add(key); + countToNodeMapping.put(1, head.next); + } + } + + public void dec(String key) { + if (keyToCountMapping.containsKey(key)) { + int count = keyToCountMapping.get(key); + if (count == 1) { + keyToCountMapping.remove(key); + removeKey(countToNodeMapping.get(count), key); + } else { + updateKey(key, -1); + } + } + } + + public String getMaxKey() { + return tail.prev == head ? "" : tail.prev.keys.iterator().next(); + } + + public String getMinKey() { + return head.next == tail ? "" : head.next.keys.iterator().next(); + } + + private void updateKey(String key, int diff) { + int count = keyToCountMapping.get(key); + keyToCountMapping.put(key, count + diff); + NodeList currNode = countToNodeMapping.get(count); + NodeList newNode; + if (countToNodeMapping.containsKey(count + diff)) { + newNode = countToNodeMapping.get(count + diff); + } else { + newNode = new NodeList(count + diff); + countToNodeMapping.put(count + diff, newNode); + // If diff == 1 then new node will have count greater than currNode else it will have count less than currNode + addNodeAfter(newNode, diff == 1 ? currNode : currNode.prev); + } + newNode.keys.add(key); + removeKey(currNode, key); + } + + private void removeKey(NodeList nodeList, String key) { + nodeList.keys.remove(key); + if (nodeList.keys.isEmpty()) { + removeNodeList(nodeList); + countToNodeMapping.remove(nodeList.count); + } + } + + private void removeNodeList(NodeList nodeList) { + nodeList.prev.next = nodeList.next; + nodeList.next.prev = nodeList.prev; + nodeList.next = null; + nodeList.prev = null; + } + + private void addNodeAfter(NodeList node, NodeList prevNode) { + node.prev = prevNode; + node.next = prevNode.next; + prevNode.next.prev = node; + prevNode.next = node; + } + + private static class NodeList { + int count; + Set keys; + NodeList next; + NodeList prev; + + public NodeList(int count) { + this.count = count; + keys = new HashSet<>(); + } + } +} + +/** + * Your AllOne object will be instantiated and called as such: + * AllOne obj = new AllOne(); + * obj.inc(key); + * obj.dec(key); + * String param_3 = obj.getMaxKey(); + * String param_4 = obj.getMinKey(); + */ diff --git a/Hard/Arithmetic Slices II - Subsequence.java b/Hard/Arithmetic Slices II - Subsequence.java new file mode 100644 index 00000000..f193579f --- /dev/null +++ b/Hard/Arithmetic Slices II - Subsequence.java @@ -0,0 +1,22 @@ +class Solution { + public int numberOfArithmeticSlices(int[] nums) { + int n = nums.length; + Map[] count = new Map[n]; + int result = 0; + for (int i = 0; i < n; i++) { + count[i] = new HashMap<>(); + for (int j = 0; j < i; j++) { + long delta = ((long) nums[i]) - ((long) nums[j]); + if (delta < Integer.MIN_VALUE || delta > Integer.MAX_VALUE) { + continue; + } + int diff = (int) delta; + int sum = count[j].getOrDefault(diff, 0); + int current = count[i].getOrDefault(diff, 0); + count[i].put(diff, current + sum + 1); + result += sum; + } + } + return result; + } +} diff --git a/Hard/Basic Calculator III.java b/Hard/Basic Calculator III.java index ab8af16e..dd97e966 100644 --- a/Hard/Basic Calculator III.java +++ b/Hard/Basic Calculator III.java @@ -1,74 +1,28 @@ class Solution { - public int calculate(String s) { - if (s.length() == 0) { - return 0; + public int calculate(String s) { + int currNum = 0; + int prevNum = 0; + int result = 0; + char operation = '+'; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (Character.isDigit(c)) { + currNum = currNum * 10 + Character.getNumericValue(c); + } + if ((!Character.isDigit(c) && !Character.isWhitespace(c)) || i == s.length() - 1) { + if (operation == '-' || operation == '+') { + result += prevNum; + prevNum = operation == '+' ? currNum : -currNum; + } else if (operation == '*') { + prevNum = prevNum * currNum; + } else { + prevNum = prevNum / currNum; } - - Stack nums = new Stack<>(); - Stack ops = new Stack<>(); - int num = 0; - - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (c == ' ') { - continue; - } - - if (Character.isDigit(c)) { - num = c - '0'; - while (i < s.length() - 1 && Character.isDigit(s.charAt(i + 1))) { - num = num * 10 + (s.charAt(i + 1) - '0'); - i++; - } - - nums.push(num); - num = 0; - } - else if (c == '(') { - ops.push(c); - } - else if (c == ')') { - while (ops.peek() != '(') { - nums.push(performOperation(ops.pop(), nums.pop(), nums.pop())); - } - ops.pop(); - } - else if (c == '+' || c == '-' || c == '*' || c == '/') { - while (!ops.isEmpty() && precedence(c, ops.peek())) { - nums.push(performOperation(ops.pop(), nums.pop(), nums.pop())); - } - - ops.push(c); - } - } - - while (!ops.isEmpty()) { - nums.push(performOperation(ops.pop(), nums.pop(), nums.pop())); - } - - return nums.pop(); - } - - private int performOperation(char op, int b, int a) { - switch (op) { - case '+': return a + b; - case '-': return a - b; - case '*': return a * b; - case '/': return a / b; - } - - return 0; - } - - private boolean precedence(char op1, char op2) { - if (op2 == '(' || op2 == ')') { - return false; - } - - if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) { - return false; - } - - return true; + operation = c; + currNum = 0; + } } + result += prevNum; + return result; + } } diff --git a/Hard/Basic Calculator.java b/Hard/Basic Calculator.java index edd9467f..1a1813d0 100644 --- a/Hard/Basic Calculator.java +++ b/Hard/Basic Calculator.java @@ -1,55 +1,29 @@ class Solution { - public static int calculate(String s) { - Stack stack = new Stack<>(); - int res = 0; - int num = 0; - int sign = 1; - boolean hasNumberStarted = false; - - for (int i=0; i stack = new Stack<>(); + int result = 0; + int number = 0; + int sign = 1; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (Character.isDigit(c)) { + number = number * 10 + Character.getNumericValue(c); + } else if (c == '+' || c == '-') { + result += sign * number; + sign = c == '+' ? 1 : -1; + number = 0; + } else if (c == '(') { + stack.push(result); + stack.push(sign); + sign = 1; + result = 0; + } else if (c == ')') { + result += sign * number; + result *= stack.pop(); + result += stack.pop(); + number = 0; + } } + return result + (sign * number); + } } diff --git a/Hard/Best Time to Buy and Sell Stock IV.java b/Hard/Best Time to Buy and Sell Stock IV.java new file mode 100644 index 00000000..8aecbd84 --- /dev/null +++ b/Hard/Best Time to Buy and Sell Stock IV.java @@ -0,0 +1,18 @@ +class Solution { + public int maxProfit(int k, int[] prices) { + if (k == 0) { + return 0; + } + int[][] dp = new int[k + 1][2]; + for (int i = 0; i <= k; i++) { + dp[i][0] = 1000; + } + for (int i = 0; i < prices.length; i++) { + for (int j = 1; j <= k; j++) { + dp[j][0] = Math.min(dp[j][0], prices[i] - dp[j - 1][1]); + dp[j][1] = Math.max(dp[j][1], prices[i] - dp[j][0]); + } + } + return dp[k][1]; + } +} diff --git a/Hard/Binary Tree Cameras.java b/Hard/Binary Tree Cameras.java new file mode 100644 index 00000000..f87825e6 --- /dev/null +++ b/Hard/Binary Tree Cameras.java @@ -0,0 +1,45 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + private final int NOT_MONITORED = 0; + private final int MONITORED_NOCAM = 1; + private final int MONITORED_WITHCAM = 2; + + public int minCameraCover(TreeNode root) { + if (root == null) { + return 0; + } + int[] cameras = {0}; + int top = dfs(root, cameras); + return cameras[0] + (top == NOT_MONITORED ? 1 : 0); + } + + private int dfs(TreeNode root, int[] cameras) { + if (root == null) { + return MONITORED_NOCAM; + } + int left = dfs(root.left, cameras); + int right = dfs(root.right, cameras); + if (left == MONITORED_NOCAM && right == MONITORED_NOCAM) { + return NOT_MONITORED; + } else if (left == NOT_MONITORED || right == NOT_MONITORED) { + cameras[0]++; + return MONITORED_WITHCAM; + } else { + return MONITORED_NOCAM; + } + } +} diff --git a/Hard/Binary Tree PostOrder Traversal.java b/Hard/Binary Tree PostOrder Traversal.java deleted file mode 100644 index 53983b32..00000000 --- a/Hard/Binary Tree PostOrder Traversal.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public List postorderTraversal(TreeNode root) { - List values = new ArrayList<>(); - if (root == null) { - return values; - } - - Stack stack1 = new Stack<>(); - Stack stack2 = new Stack<>(); - - stack1.push(root); - - while (!stack1.empty()) { - TreeNode temp = stack1.pop(); - stack2.push(temp); - - if (temp.left != null) { - stack1.push(temp.left); - } - - if (temp.right != null) { - stack1.push(temp.right); - } - } - - while (!stack2.empty()) { - values.add(stack2.pop().val); - } - - return values; - } -} diff --git a/Hard/Build Array Where You Can Find The Maximum Exactly K Comparisons.java b/Hard/Build Array Where You Can Find The Maximum Exactly K Comparisons.java new file mode 100644 index 00000000..c7ede11f --- /dev/null +++ b/Hard/Build Array Where You Can Find The Maximum Exactly K Comparisons.java @@ -0,0 +1,28 @@ +class Solution { + + private static final int MOD = (int) 1000_000_007; + + public int numOfArrays(int n, int m, int k) { + int[][][] dp = new int[n + 1][m + 1][k + 1]; + for (int i = 0; i < dp[0].length; i++) { + dp[n][i][0] = 1; + } + for (int i = n - 1; i >= 0; i--) { + for (int j = m; j >= 0; j--) { + for (int l = 0; l <= k; l++) { + int result = 0; + for (int num = 1; num <= j; num++) { + result = (result + dp[i + 1][j][l]) % MOD; + } + if (l > 0) { + for (int num = j + 1; num <= m; num++) { + result = (result + dp[i + 1][num][l - 1]) % MOD; + } + } + dp[i][j][l] = result; + } + } + } + return dp[0][0][k]; + } +} diff --git a/Hard/Bus Routes.java b/Hard/Bus Routes.java new file mode 100644 index 00000000..54c2762a --- /dev/null +++ b/Hard/Bus Routes.java @@ -0,0 +1,39 @@ +class Solution { + public int numBusesToDestination(int[][] routes, int source, int target) { + if (source == target) { + return 0; + } + Map> stopToBusMapping = new HashMap<>(); + for (int i = 0; i < routes.length; i++) { + for (int stop : routes[i]) { + stopToBusMapping.computeIfAbsent(stop, k -> new HashSet<>()).add(i); + } + } + Queue queue = new LinkedList<>(); + Set visited = new HashSet<>(); + for (int route : stopToBusMapping.get(source)) { + queue.add(route); + visited.add(route); + } + int buses = 1; + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + int removed = queue.remove(); + for (int stop : routes[removed]) { + if (stop == target) { + return buses; + } + for (int nextBus : stopToBusMapping.getOrDefault(stop, new HashSet<>())) { + if (!visited.contains(nextBus)) { + visited.add(nextBus); + queue.add(nextBus); + } + } + } + } + buses++; + } + return -1; + } +} diff --git a/Hard/Candy.java b/Hard/Candy.java index ed787668..269d4d6a 100644 --- a/Hard/Candy.java +++ b/Hard/Candy.java @@ -1,23 +1,22 @@ class Solution { - public int candy(int[] ratings) { - int[] leftCandy = new int[ratings.length]; - int[] rightCandy = new int[ratings.length]; - Arrays.fill(leftCandy, 1); - Arrays.fill(rightCandy, 1); - for (int i = 1; i < ratings.length; i++) { - if (ratings[i] > ratings[i - 1]) { - leftCandy[i] = leftCandy[i - 1] + 1; - } + public int candy(int[] ratings) { + int n = ratings.length; + int[] candies = new int[n]; + Arrays.fill(candies, 1); + for (int i = 1; i < n; i++) { + if (ratings[i] > ratings[i - 1]) { + candies[i] = candies[i - 1] + 1; + } + } + for (int i = n - 2; i >= 0; i--) { + if (ratings[i] > ratings[i + 1]) { + candies[i] = Math.max(candies[i], candies[i + 1] + 1); + } + } + int totalCandies = 0; + for (int i = 0; i < n; i++) { + totalCandies += candies[i]; + } + return totalCandies; } - for (int i = ratings.length - 2; i >= 0; i--) { - if (ratings[i] > ratings[i + 1]) { - rightCandy[i] = rightCandy[i + 1] + 1; - } - } - int numOfCandies = 0; - for (int i = 0; i < ratings.length; i++) { - numOfCandies += Math.max(leftCandy[i], rightCandy[i]); - } - return numOfCandies; - } } diff --git a/Hard/Checking Existence of Edge Length Limited Paths.java b/Hard/Checking Existence of Edge Length Limited Paths.java new file mode 100644 index 00000000..d03848ef --- /dev/null +++ b/Hard/Checking Existence of Edge Length Limited Paths.java @@ -0,0 +1,41 @@ +class Solution { + public boolean[] distanceLimitedPathsExist(int n, int[][] edgeList, int[][] queries) { + UnionFind unionFind = new UnionFind(n); + for (int i = 0; i < queries.length; i++) { + queries[i] = new int[]{queries[i][0], queries[i][1], queries[i][2], i}; + } + Arrays.sort(queries, Comparator.comparingInt(a -> a[2])); + Arrays.sort(edgeList, Comparator.comparingInt(a -> a[2])); + boolean[] result = new boolean[queries.length]; + for (int i = 0, j = 0; i < queries.length; i++) { + int[] query = queries[i]; + while (j < edgeList.length && edgeList[j][2] < query[2]) { + unionFind.union(edgeList[j][0], edgeList[j++][1]); + } + result[query[3]] = unionFind.find(query[0]) == unionFind.find(query[1]); + } + return result; + } + + private static class UnionFind { + private final int[] parent; + + public UnionFind(int n) { + this.parent = new int[n]; + for (int i = 0; i < n; i++) { + parent[i] = i; + } + } + + public int find(int node) { + if (parent[node] != node) { + parent[node] = find(parent[node]); + } + return parent[node]; + } + + public void union(int x, int y) { + parent[find(x)] = parent[find(y)]; + } + } +} diff --git a/Hard/Cherry Pickup II.java b/Hard/Cherry Pickup II.java new file mode 100644 index 00000000..1786e8cc --- /dev/null +++ b/Hard/Cherry Pickup II.java @@ -0,0 +1,32 @@ +class Solution { + public int cherryPickup(int[][] grid) { + int m = grid.length; + int n = grid[0].length; + Integer[][][] cache = new Integer[m][n][n]; + return recurse(0, 0, n - 1, grid, cache); + } + + private int recurse(int row, int colOne, int colTwo, int[][] grid, Integer[][][] cache) { + if (colOne < 0 || colOne >= grid[0].length || colTwo < 0 || colTwo >= grid[0].length) { + return 0; + } + if (cache[row][colOne][colTwo] != null) { + return cache[row][colOne][colTwo]; + } + int result = 0; + result += grid[row][colOne]; + if (colOne != colTwo) { + result += grid[row][colTwo]; + } + if (row != grid.length - 1) { + int max = 0; + for (int c1 = colOne - 1; c1 <= colOne + 1; c1++) { + for (int c2 = colTwo - 1; c2 <= colTwo + 1; c2++) { + max = Math.max(max, recurse(row + 1, c1, c2, grid, cache)); + } + } + result += max; + } + return cache[row][colOne][colTwo] = result; + } +} diff --git a/Hard/Constrained Subsequence Sum.java b/Hard/Constrained Subsequence Sum.java new file mode 100644 index 00000000..9dabd1d4 --- /dev/null +++ b/Hard/Constrained Subsequence Sum.java @@ -0,0 +1,16 @@ +class Solution { + public int constrainedSubsetSum(int[] nums, int k) { + PriorityQueue pq = new PriorityQueue<>((a, b) -> b[0] - a[0]); + pq.add(new int[]{nums[0], 0}); + int result = nums[0]; + for (int i = 1; i < nums.length; i++) { + while (i - pq.peek()[1] > k) { + pq.remove(); + } + int curr = Math.max(0, pq.peek()[0]) + nums[i]; + result = Math.max(result, curr); + pq.add(new int[]{curr, i}); + } + return result; + } +} diff --git a/Hard/Construct Target Array With Multiple Sums.java b/Hard/Construct Target Array With Multiple Sums.java new file mode 100644 index 00000000..a8a71438 --- /dev/null +++ b/Hard/Construct Target Array With Multiple Sums.java @@ -0,0 +1,28 @@ +class Solution { + public boolean isPossible(int[] target) { + if (target.length == 1) { + return target[0] == 1; + } + PriorityQueue pq = new PriorityQueue<>((a, b) -> b - a); + int sum = 0; + for (int num : target) { + sum += num; + pq.add(num); + } + int n = target.length; + while (pq.peek() > 1) { + int largest = pq.poll(); + int remaining = sum - largest; + if (remaining == 1) { + return true; + } + int delta = largest % remaining; + if (delta == 0 || delta == largest) { + return false; + } + pq.add(delta); + sum = sum - largest + delta; + } + return true; + } +} diff --git a/Hard/Count Subarrays With Fixed Bounds.java b/Hard/Count Subarrays With Fixed Bounds.java new file mode 100644 index 00000000..2846d647 --- /dev/null +++ b/Hard/Count Subarrays With Fixed Bounds.java @@ -0,0 +1,21 @@ +class Solution { + public long countSubarrays(int[] nums, int minK, int maxK) { + long result = 0; + int minPosition = -1; + int maxPosition = -1; + int leftIdx = -1; + for (int i = 0; i < nums.length; i++) { + if (nums[i] < minK || nums[i] > maxK) { + leftIdx = i; + } + if (nums[i] == minK) { + minPosition = i; + } + if (nums[i] == maxK) { + maxPosition = i; + } + result += Math.max(0, Math.min(maxPosition, minPosition) - leftIdx); + } + return result; + } +} diff --git a/Hard/Count Vowels Permutation.java b/Hard/Count Vowels Permutation.java new file mode 100644 index 00000000..a0a2c36c --- /dev/null +++ b/Hard/Count Vowels Permutation.java @@ -0,0 +1,24 @@ +class Solution { + public int countVowelPermutation(int n) { + long aCount = 1; + long eCount = 1; + long iCount = 1; + long oCount = 1; + long uCount = 1; + final int MOD = 1000000007; + for (int i = 1; i < n; i++) { + long aCountNew = (eCount + iCount + uCount) % MOD; + long eCountNew = (aCount + iCount) % MOD; + long iCountNew = (eCount + oCount) % MOD; + long oCountNew = (iCount) % MOD; + long uCountNew = (iCount + oCount) % MOD; + aCount = aCountNew; + eCount = eCountNew; + iCount = iCountNew; + oCount = oCountNew; + uCount = uCountNew; + } + long result = (aCount + eCount + iCount + oCount + uCount) % MOD; + return (int) result; + } +} diff --git a/Hard/Count of Smaller Numbers After Self.java b/Hard/Count of Smaller Numbers After Self.java new file mode 100644 index 00000000..30f10d48 --- /dev/null +++ b/Hard/Count of Smaller Numbers After Self.java @@ -0,0 +1,50 @@ +class Solution { + public List countSmaller(int[] nums) { + int n = nums.length; + int[] result = new int[n]; + int[] indices = new int[n]; + for (int i = 0; i < n; i++) { + indices[i] = i; + } + mergesort(indices, 0, n, result, nums); + return Arrays.stream(result).boxed().collect(Collectors.toList()); + } + + private void mergesort(int[] indices, int left, int right, int[] result, int[] nums) { + if (right - left <= 1) { + return; + } + int mid = (left + right) / 2; + mergesort(indices, left, mid, result, nums); + mergesort(indices, mid, right, result, nums); + merge(indices, left, right, mid, result, nums); + } + + private void merge(int[] indices, int left, int right, int mid, int[] result, int[] nums) { + int i = left; + int j = mid; + List temp = new ArrayList<>(); + while (i < mid && j < right) { + if (nums[indices[i]] <= nums[indices[j]]) { + result[indices[i]] += j - mid; + temp.add(indices[i]); + i++; + } else { + temp.add(indices[j]); + j++; + } + } + while (i < mid) { + result[indices[i]] += j - mid; + temp.add(indices[i]); + i++; + } + while (j < right) { + temp.add(indices[j]); + j++; + } + for (int k = left; k < right; k++) { + indices[k] = temp.get(k - left); + } + } +} diff --git a/Hard/Course Schedule III.java b/Hard/Course Schedule III.java new file mode 100644 index 00000000..ceea807c --- /dev/null +++ b/Hard/Course Schedule III.java @@ -0,0 +1,17 @@ +class Solution { + public int scheduleCourse(int[][] courses) { + Arrays.sort(courses, (a, b) -> a[1] - b[1]); + PriorityQueue queue = new PriorityQueue<>((a, b) -> b - a); + int time = 0; + for (int[] course : courses) { + if (time + course[0] <= course[1]) { + queue.add(course[0]); + time += course[0]; + } else if (!queue.isEmpty() && queue.peek() > course[0]) { + time += course[0] - queue.poll(); + queue.add(course[0]); + } + } + return queue.size(); + } +} diff --git a/Hard/Critical Connections in a Network.java b/Hard/Critical Connections in a Network.java new file mode 100644 index 00000000..92d73cb4 --- /dev/null +++ b/Hard/Critical Connections in a Network.java @@ -0,0 +1,49 @@ +class Solution { + public List> criticalConnections(int n, List> connections) { + Map> graph = new HashMap<>(); + Map rank = new HashMap<>(); + Set connectionSet = new HashSet<>(); + buildGraph(n, connections, graph, rank, connectionSet); + dfs(0, 0, graph, rank, connectionSet); + List> result = new ArrayList<>(); + for (String conn : connectionSet) { + int nodeOne = Integer.parseInt(conn.split("-")[0]); + int nodeTwo = Integer.parseInt(conn.split("-")[1]); + result.add(Arrays.asList(nodeOne, nodeTwo)); + } + return result; + } + + private void buildGraph(int n, List> connections, Map> graph, Map rank, Set connectionSet) { + for (int i = 0; i < n; i++) { + graph.put(i, new ArrayList<>()); + rank.put(i, null); + } + for (List edge : connections) { + graph.get(edge.get(0)).add(edge.get(1)); + graph.get(edge.get(1)).add(edge.get(0)); + connectionSet.add( + Math.min(edge.get(0), edge.get(1)) + "-" + Math.max(edge.get(0), edge.get(1))); + } + } + + private int dfs(int node, int discoveryRank, Map> graph, Map rank, Set connectionSet) { + if (rank.get(node) != null) { + return rank.get(node); + } + rank.put(node, discoveryRank); + int minimumRank = discoveryRank + 1; + for (Integer neighbor : graph.get(node)) { + Integer neighborRank = rank.get(neighbor); + if (neighborRank != null && neighborRank == discoveryRank - 1) { + continue; + } + int recursiveRank = dfs(neighbor, discoveryRank + 1, graph, rank, connectionSet); + if (recursiveRank <= discoveryRank) { + connectionSet.remove(Math.min(node, neighbor) + "-" + Math.max(node, neighbor)); + } + minimumRank = Math.min(minimumRank, recursiveRank); + } + return minimumRank; + } +} diff --git a/Hard/Design Graph With Shortest Path Calculator.java b/Hard/Design Graph With Shortest Path Calculator.java new file mode 100644 index 00000000..0b7fddf1 --- /dev/null +++ b/Hard/Design Graph With Shortest Path Calculator.java @@ -0,0 +1,43 @@ +class Graph { + + private final Map> graph; + + public Graph(int n, int[][] edges) { + this.graph = new HashMap<>(); + for (int[] edge : edges) { + graph.computeIfAbsent(edge[0], k -> new ArrayList<>()).add(new Connection(edge[1], edge[2])); + } + } + + public void addEdge(int[] edge) { + graph.computeIfAbsent(edge[0], k -> new ArrayList<>()).add(new Connection(edge[1], edge[2])); + } + + public int shortestPath(int node1, int node2) { + PriorityQueue queue = new PriorityQueue<>(Comparator.comparingInt(a -> a[1])); + queue.add(new int[]{node1, 0}); + Set seen = new HashSet<>(); + while (!queue.isEmpty()) { + int[] removed = queue.remove(); + int node = removed[0]; + if (node == node2) { + return removed[1]; + } + if (graph.containsKey(node) && seen.add(node)) { + for (Connection connection : graph.getOrDefault(removed[0], new ArrayList<>())) { + queue.add(new int[]{connection.node, removed[1] + connection.cost}); + } + } + } + return -1; + } + + private record Connection(int node, int cost) { } +} + +/** + * Your Graph object will be instantiated and called as such: + * Graph obj = new Graph(n, edges); + * obj.addEdge(edge); + * int param_2 = obj.shortestPath(node1,node2); + */ diff --git a/Hard/Design In-Memory File System.java b/Hard/Design In-Memory File System.java new file mode 100644 index 00000000..9002c758 --- /dev/null +++ b/Hard/Design In-Memory File System.java @@ -0,0 +1,155 @@ +import java.util.Optional; + +class FileSystem { + + private final Node root; + + public FileSystem() { + this.root = new DirectoryNode("/"); + } + + public List ls(String path) { + String[] splits = path.split("/"); + if (splits.length == 0) { + return buildlsResult((DirectoryNode) root); + } + Node curr = root; + for (int i = 1; i < splits.length - 1; i++) { + curr = ((DirectoryNode) curr).getNode(splits[i]).get(); + } + Node lastNode = ((DirectoryNode) curr).getNode(splits[splits.length - 1]).get(); + if (lastNode.isFile()) { + return Collections.singletonList(lastNode.getName()); + } + return buildlsResult((DirectoryNode) lastNode); + } + + public void mkdir(String path) { + String[] splits = path.split("/"); + createIfNotExists(splits); + } + + public void addContentToFile(String filePath, String content) { + String[] splits = filePath.split("/"); + DirectoryNode directoryNode = createIfNotExists(Arrays.copyOfRange(splits, 0, splits.length)); + String fileName = splits[splits.length - 1]; + if (directoryNode.getNode(fileName).isEmpty()) { + FileNode fileNode = new FileNode(fileName); + directoryNode.addContent(fileName, fileNode); + } + FileNode fileNode = (FileNode) directoryNode.getNode(fileName).get(); + fileNode.addContent(content); + } + + public String readContentFromFile(String filePath) { + String[] splits = filePath.split("/"); + DirectoryNode directoryNode = createIfNotExists(Arrays.copyOfRange(splits, 0, splits.length)); + String fileName = splits[splits.length - 1]; + FileNode fileNode = (FileNode) directoryNode.getNode(fileName).get(); + return fileNode.getContents(); + } + + private static List buildlsResult(DirectoryNode curr) { + return curr + .getContents() + .stream() + .map(Node::getName) + .sorted() + .collect(Collectors.toList()); + } + + private DirectoryNode createIfNotExists(String[] splits) { + DirectoryNode curr = (DirectoryNode) root; + for (int i = 1; i < splits.length; i++) { + Optional nextDirectory = curr.getNode(splits[i]); + if (nextDirectory.isEmpty()) { + DirectoryNode node = new DirectoryNode(splits[i]); + curr.addContent(splits[i], node); + curr = node; + } else { + curr = (DirectoryNode) nextDirectory.get(); + } + } + return curr; + } + + private static class FileNode implements Node { + + private final String name; + + private final StringBuilder contents; + + public FileNode(String name) { + this.name = name; + this.contents = new StringBuilder(); + } + + public void addContent(String content) { + this.contents.append(content); + } + + public String getContents() { + return contents.toString(); + } + + @Override + public String getName() { + return this.name; + } + + @Override + public boolean isFile() { + return true; + } + } + + private static class DirectoryNode implements Node { + + private String name; + + private final Map contents; + + public DirectoryNode(String name) { + this.name = name; + this.contents = new HashMap<>(); + } + + @Override + public String getName() { + return name; + } + + @Override + public boolean isFile() { + return false; + } + + public void addContent(String key, Node node) { + contents.put(key, node); + } + + public List getContents() { + return contents.values().stream().toList(); + } + + public Optional getNode(String nodeName) { + return Optional.ofNullable(contents.getOrDefault(nodeName, null)); + } + } + + private interface Node { + + String getName(); + + boolean isFile(); + } +} + +/** + * Your FileSystem object will be instantiated and called as such: + * FileSystem obj = new FileSystem(); + * List param_1 = obj.ls(path); + * obj.mkdir(path); + * obj.addContentToFile(filePath,content); + * String param_4 = obj.readContentFromFile(filePath); + */ diff --git a/Hard/Design Movie Rental System.java b/Hard/Design Movie Rental System.java new file mode 100644 index 00000000..0aaeb6c8 --- /dev/null +++ b/Hard/Design Movie Rental System.java @@ -0,0 +1,102 @@ +class MovieRentingSystem { + + Comparator comparator = + (o1, o2) -> { + if (o1.price != o2.price) { + return o1.price - o2.price; + } + if (o1.shopId != o2.shopId) { + return o1.shopId - o2.shopId; + } + return o1.movieId - o2.movieId; + }; + Map> movieToUnrentedShopMapping; + Map shopMoviePairToPriceMapping; + TreeSet rentedMovies; + + public MovieRentingSystem(int n, int[][] entries) { + movieToUnrentedShopMapping = new HashMap<>(); + shopMoviePairToPriceMapping = new HashMap<>(); + rentedMovies = new TreeSet<>(comparator); + for (int[] entry : entries) { + movieToUnrentedShopMapping + .computeIfAbsent(entry[1], k -> new TreeSet<>(comparator)) + .add(new MovieEntry(entry[1], entry[2], entry[0])); + shopMoviePairToPriceMapping.put(new ShopMoviePair(entry[0], entry[1]), entry[2]); + } + } + + public List search(int movie) { + return movieToUnrentedShopMapping.getOrDefault(movie, Collections.emptySet()).stream() + .limit(5) + .map(e -> e.shopId) + .collect(Collectors.toList()); + } + + public void rent(int shop, int movie) { + int price = shopMoviePairToPriceMapping.get(new ShopMoviePair(shop, movie)); + movieToUnrentedShopMapping.get(movie).remove(new MovieEntry(movie, price, shop)); + rentedMovies.add(new MovieEntry(movie, price, shop)); + } + + public void drop(int shop, int movie) { + int price = shopMoviePairToPriceMapping.get(new ShopMoviePair(shop, movie)); + movieToUnrentedShopMapping.get(movie).add(new MovieEntry(movie, price, shop)); + rentedMovies.remove(new MovieEntry(movie, price, shop)); + } + + public List> report() { + return rentedMovies.stream() + .limit(5) + .map(e -> List.of(e.shopId, e.movieId)) + .collect(Collectors.toList()); + } + + class ShopMoviePair { + int shopId; + int movieId; + + public ShopMoviePair(int shopId, int movieId) { + this.shopId = shopId; + this.movieId = movieId; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ShopMoviePair that = (ShopMoviePair) o; + return shopId == that.shopId && movieId == that.movieId; + } + + @Override + public int hashCode() { + return Objects.hash(shopId, movieId); + } + } + + class MovieEntry { + int movieId; + int price; + int shopId; + + public MovieEntry(int movieId, int price, int shopId) { + this.movieId = movieId; + this.price = price; + this.shopId = shopId; + } + } +} + +/** + * Your MovieRentingSystem object will be instantiated and called as such: + * MovieRentingSystem obj = new MovieRentingSystem(n, entries); + * List param_1 = obj.search(movie); + * obj.rent(shop,movie); + * obj.drop(shop,movie); + * List> param_4 = obj.report(); + */ diff --git a/Hard/Design Search Autocomplete System.java b/Hard/Design Search Autocomplete System.java index 98888b69..c4c15c9e 100644 --- a/Hard/Design Search Autocomplete System.java +++ b/Hard/Design Search Autocomplete System.java @@ -1,84 +1,76 @@ class AutocompleteSystem { - Map map; - Node root; - Node currNode; + + private final TrieNode root; + private TrieNode queryNode; + private final Map popularityMap; StringBuilder sb; boolean invalidQuery; + public AutocompleteSystem(String[] sentences, int[] times) { - map = new HashMap<>(); - root = new Node('-'); + root = new TrieNode(); + this.popularityMap = new HashMap<>(); for (int i = 0; i < sentences.length; i++) { - addSentence(sentences[i], 0, root); - map.put(sentences[i], map.getOrDefault(sentences[i], 0) + times[i]); + indexSentence(sentences[i], root); + this.popularityMap.put( + sentences[i], this.popularityMap.getOrDefault(sentences[i], 0) + times[i]); } - currNode = root; - invalidQuery = false; - sb = new StringBuilder(); + this.queryNode = root; + this.sb = new StringBuilder(); + this.invalidQuery = false; } - - private void addSentence(String s, int idx, Node root) { - if (idx == s.length()) { - return; - } - char c = s.charAt(idx); - if (!root.children.containsKey(c)) { - root.children.put(c, new Node(c)); + + private void indexSentence(String sentence, TrieNode root) { + for (char c : sentence.toCharArray()) { + if (!root.children.containsKey(c)) { + root.children.put(c, new TrieNode()); + } + root = root.children.get(c); + root.sentences.add(sentence); } - Node node = root.children.get(c); - node.possibleSentences.add(s); - addSentence(s, idx + 1, node); } public List input(char c) { if (c == '#') { - String s = sb.toString(); - map.put(s, map.getOrDefault(s, 0) + 1); - addSentence(s, 0, root); - sb.setLength(0); - currNode = root; - invalidQuery = false; + cleanUp(); return new ArrayList<>(); } - sb.append(c); - if (!currNode.children.containsKey(c) || invalidQuery) { - invalidQuery = true; + this.sb.append(c); + if (!this.queryNode.children.containsKey(c) || invalidQuery) { + this.invalidQuery = true; return new ArrayList<>(); } - else { - List possibleSentences = new ArrayList<>(); - currNode = currNode.children.get(c); - possibleSentences.addAll(currNode.possibleSentences); - return getTopThree(possibleSentences); - } + this.queryNode = this.queryNode.children.get(c); + return this.queryNode.sentences.stream() + .sorted( + (o1, o2) -> { + int c1 = popularityMap.get(o2).compareTo(popularityMap.get(o1)); + if (c1 != 0) { + return c1; + } + return o1.compareTo(o2); + }) + .limit(3) + .collect(Collectors.toList()); } - - private List getTopThree(List list) { - Collections.sort(list, new Comparator(){ - public int compare(String s1, String s2) { - int c = map.get(s2) - map.get(s1); - if (c != 0) { - return c; - } - return s1.compareTo(s2); - } - }); - List ans = new ArrayList<>(); - for (int i = 0; i < list.size() && ans.size() < 3; i++) { - ans.add(list.get(i)); - } - return ans; + + private void cleanUp() { + this.queryNode = root; + String inputString = this.sb.toString(); + this.sb.setLength(0); + this.popularityMap.put(inputString, this.popularityMap.getOrDefault(inputString, 0) + 1); + this.invalidQuery = false; + indexSentence(inputString, root); } -} -class Node { - char c; - Map children; - Set possibleSentences; - - public Node(char c) { - this.c = c; - children = new HashMap<>(); - possibleSentences = new HashSet<>(); + private static class TrieNode { + + private final Map children; + private final Set sentences; + + public TrieNode() { + this.children = new HashMap<>(); + this.sentences = new HashSet<>(); + } } } diff --git a/Hard/Design Skiplist.java b/Hard/Design Skiplist.java new file mode 100644 index 00000000..8554fcb7 --- /dev/null +++ b/Hard/Design Skiplist.java @@ -0,0 +1,86 @@ +class Skiplist { + + private Node head; + private Random random; + + public Skiplist() { + this.head = new Node(-1); + this.random = new Random(); + } + + public boolean search(int target) { + Node curr = head; + while (curr != null) { + while (curr.next != null && curr.next.val < target) { + curr = curr.next; + } + if (curr.next != null && curr.next.val == target) { + return true; + } + curr = curr.down; + } + return false; + } + + public void add(int num) { + Stack stack = new Stack<>(); + Node curr = head; + while (curr != null) { + while (curr.next != null && curr.next.val < num) { + curr = curr.next; + } + stack.push(curr); + curr = curr.down; + } + boolean newLevel = true; + Node downNode = null; + while (newLevel && !stack.isEmpty()) { + curr = stack.pop(); + Node newNode = new Node(num); + newNode.next = curr.next; + newNode.down = downNode; + curr.next = newNode; + downNode = curr.next; + newLevel = random.nextDouble() < 0.5; + } + if (newLevel) { + Node prevHead = head; + head = new Node(-1); + head.down = prevHead; + } + } + + public boolean erase(int num) { + Node curr = head; + boolean found = false; + while (curr != null) { + while (curr.next != null && curr.next.val < num) { + curr = curr.next; + } + if (curr.next != null && curr.next.val == num) { + found = true; + curr.next = curr.next.next; + } + curr = curr.down; + } + return found; + } + + private static class Node { + int val; + Node next; + Node down; + + public Node(int val) { + this.val = val; + } + } +} + +/** + * Your Skiplist object will be instantiated and called as such: + * Skiplist obj = new Skiplist(); + * boolean param_1 = obj.search(target); + * obj.add(num); + * boolean param_3 = obj.erase(num); + */ diff --git a/Hard/Dice Roll Simulation.java b/Hard/Dice Roll Simulation.java new file mode 100644 index 00000000..47ba0ce5 --- /dev/null +++ b/Hard/Dice Roll Simulation.java @@ -0,0 +1,29 @@ +class Solution { + private final long MOD = (long) Math.pow(10, 9) + 7; + + public int dieSimulator(int n, int[] rollMax) { + long[][] dp = new long[n][7]; + for(int i = 0; i < 6; i++) { + dp[0][i] = 1; + } + dp[0][6] = 6; + for(int i = 1; i < n; i++) { + long sum = 0; + for(int j = 0; j < 6; j++) { + dp[i][j] = dp[i - 1][6]; + if (i - rollMax[j] < 0) { + sum = (sum + dp[i][j]) % MOD; + } else { + if (i - rollMax[j] - 1 >= 0) { + dp[i][j] = (dp[i][j] - (dp[i - rollMax[j] - 1][6] - dp[i - rollMax[j] - 1][j])) % MOD + MOD; + } else { + dp[i][j] = (dp[i][j] - 1) % MOD; + } + sum = (sum + dp[i][j]) % MOD; + } + } + dp[i][6] = sum; + } + return (int) (dp[n - 1][6]); + } +} diff --git a/Hard/Edit Distance.java b/Hard/Edit Distance.java index e3428cdc..b7ae5930 100644 --- a/Hard/Edit Distance.java +++ b/Hard/Edit Distance.java @@ -1,32 +1,34 @@ class Solution { - public int minDistance(String s1, String s2) { - return minDistanceHelperDP(s1, s2, s1.length(), s2.length()); + public int minDistance(String word1, String word2) { + return minDistanceHelper( + word1, + word2, + word1.length(), + word2.length(), + new Integer[word1.length() + 1][word2.length() + 1]); } - - private int minDistanceHelperDP(String s1, String s2, int m, int n) { - int[][] dp = new int[m+1][n+1]; - for (int i=0;i<=m;i++) { - for (int j=0;j<=n;j++) { - // First substring is empty - if (i == 0) { - dp[i][j] = j; - } - // Second substring is empty - else if (j == 0) { - dp[i][j] = i; - } - // If character are same, value is same as the previous dp array - else if (s1.charAt(i-1) == s2.charAt(j-1)) { - dp[i][j] = dp[i-1][j-1]; - } - // If different, then 1 + min - else { - dp[i][j] = 1 + Math.min(dp[i-1][j-1], Math.min(dp[i][j-1], dp[i-1][j])); - } - } + private int minDistanceHelper(String word1, String word2, int word1Index, int word2Index, Integer[][] memo) { + if (word1Index == 0) { + return word2Index; } - - return dp[m][n]; + if (word2Index == 0) { + return word1Index; + } + if (memo[word1Index][word2Index] != null) { + return memo[word1Index][word2Index]; + } + int minEditDistance = 0; + if (word1.charAt(word1Index - 1) == word2.charAt(word2Index - 1)) { + minEditDistance = minDistanceHelper(word1, word2, word1Index - 1, word2Index - 1, memo); + } else { + int distanceWithInsertion = minDistanceHelper(word1, word2, word1Index, word2Index - 1, memo); + int distanceWithDeletion = minDistanceHelper(word1, word2, word1Index - 1, word2Index, memo); + int distanceWithReplace = minDistanceHelper(word1, word2, word1Index - 1, word2Index - 1, memo); + minEditDistance = Math.min(distanceWithInsertion, + Math.min(distanceWithDeletion, distanceWithReplace)) + 1; + } + memo[word1Index][word2Index] = minEditDistance; + return minEditDistance; } } diff --git a/Hard/Expression Add Operators.java b/Hard/Expression Add Operators.java new file mode 100644 index 00000000..57e56235 --- /dev/null +++ b/Hard/Expression Add Operators.java @@ -0,0 +1,29 @@ +class Solution { + public List addOperators(String num, int target) { + List result = new ArrayList<>(); + helper(num, target, "", result, 0, 0, 0); + return result; + } + + private void helper(String s, long target, String path, List result, int pos, long calculatedResult, long multed) { + if (pos == s.length()) { + if (calculatedResult == target) { + result.add(new String(path)); + } + return; + } + for (int i = pos; i < s.length(); i++) { + if (i != pos && s.charAt(pos) == '0') { + break; + } + long curr = Long.parseLong(s.substring(pos, i + 1)); + if (pos == 0) { + helper(s, target, path + curr, result, i + 1, curr, curr); + } else { + helper(s, target, path + "+" + curr, result, i + 1, calculatedResult + curr, curr); + helper(s, target, path + "-" + curr, result, i + 1, calculatedResult - curr, -curr); + helper(s, target, path + "*" + curr, result, i + 1, calculatedResult - multed + multed * curr, multed * curr); + } + } + } +} diff --git a/Hard/Find All People With Secret.java b/Hard/Find All People With Secret.java new file mode 100644 index 00000000..b18f289a --- /dev/null +++ b/Hard/Find All People With Secret.java @@ -0,0 +1,39 @@ +class Solution { + public List findAllPeople(int n, int[][] meetings, int firstPerson) { + Map> graph = new HashMap<>(); + for (int[] meeting : meetings) { + int x = meeting[0]; + int y = meeting[1]; + int time = meeting[2]; + graph.computeIfAbsent(x, k -> new ArrayList<>()).add(new int[]{time, y}); + graph.computeIfAbsent(y, k -> new ArrayList<>()).add(new int[]{time, x}); + } + int[] earliestTime = new int[n]; + Arrays.fill(earliestTime, Integer.MAX_VALUE); + earliestTime[0] = 0; + earliestTime[firstPerson] = 0; + Queue queue = new LinkedList<>(); + queue.add(new int[]{0, 0}); + queue.add(new int[]{firstPerson, 0}); + while (!queue.isEmpty()) { + int[] removed = queue.poll(); + int person = removed[0]; + int time = removed[1]; + for (int[] conn : graph.getOrDefault(person, new ArrayList<>())) { + int t = conn[0]; + int p = conn[1]; + if (t >= time && earliestTime[p] > t) { + earliestTime[p] = t; + queue.add(new int[]{p, t}); + } + } + } + List result = new ArrayList<>(); + for (int i = 0; i < n; i++) { + if (earliestTime[i] != Integer.MAX_VALUE) { + result.add(i); + } + } + return result; + } +} diff --git a/Hard/Find K-th Smallest Pair Distance.java b/Hard/Find K-th Smallest Pair Distance.java new file mode 100644 index 00000000..6d84cfa8 --- /dev/null +++ b/Hard/Find K-th Smallest Pair Distance.java @@ -0,0 +1,31 @@ +class Solution { + public int smallestDistancePair(int[] nums, int k) { + Arrays.sort(nums); + int n = nums.length; + int left = 0; + int right = nums[n - 1] - nums[0]; + while (left < right) { + int mid = (left + right) / 2; + int count = countPairs(nums, mid); + if (count < k) { + left = mid + 1; + } else { + right = mid; + } + } + return left; + } + + private int countPairs(int[] nums, int distance) { + int count = 0; + int n = nums.length; + int left = 0; + for (int i = 0; i < n; i++) { + while (nums[i] - nums[left] > distance) { + left++; + } + count += i - left; + } + return count; + } +} diff --git a/Hard/Find Median From Data Stream.java b/Hard/Find Median From Data Stream.java deleted file mode 100644 index a62a5e96..00000000 --- a/Hard/Find Median From Data Stream.java +++ /dev/null @@ -1,35 +0,0 @@ -class MedianFinder { - - /** initialize your data structure here. */ - PriorityQueue smaller; - PriorityQueue bigger; - public MedianFinder() { - smaller = new PriorityQueue<>((a, b) -> b - a); - bigger = new PriorityQueue<>(); - } - - public void addNum(int num) { - smaller.add(num); - bigger.add(smaller.poll()); - if (smaller.size() < bigger.size()) { - smaller.add(bigger.poll()); - } - } - - public double findMedian() { - if (smaller.size() == 0 && bigger.size() == 0) { - return 0.0; - } - if (smaller.size() > bigger.size()) { - return (double) smaller.peek(); - } - return ((double) smaller.peek() + bigger.peek()) / 2; - } -} - -/** - * Your MedianFinder object will be instantiated and called as such: - * MedianFinder obj = new MedianFinder(); - * obj.addNum(num); - * double param_2 = obj.findMedian(); - */ diff --git a/Hard/Find Median from Data Stream.java b/Hard/Find Median from Data Stream.java new file mode 100644 index 00000000..89269294 --- /dev/null +++ b/Hard/Find Median from Data Stream.java @@ -0,0 +1,31 @@ +class MedianFinder { + + private final PriorityQueue minQueue; + private final PriorityQueue maxQueue; + + public MedianFinder() { + this.minQueue = new PriorityQueue<>(); + this.maxQueue = new PriorityQueue<>((a, b) -> b - a); + } + + public void addNum(int num) { + maxQueue.add(num); + minQueue.add(maxQueue.poll()); + if (maxQueue.size() < minQueue.size()) { + maxQueue.add(minQueue.poll()); + } + } + + public double findMedian() { + return maxQueue.size() > minQueue.size() ? + ((double) maxQueue.peek()) : + ((maxQueue.peek() + minQueue.peek()) / (2.0)); + } +} + +/** + * Your MedianFinder object will be instantiated and called as such: + * MedianFinder obj = new MedianFinder(); + * obj.addNum(num); + * double param_2 = obj.findMedian(); + */ diff --git a/Hard/Find in Mountain Array.java b/Hard/Find in Mountain Array.java new file mode 100644 index 00000000..d030c247 --- /dev/null +++ b/Hard/Find in Mountain Array.java @@ -0,0 +1,49 @@ +/** + * // This is MountainArray's API interface. + * // You should not implement it, or speculate about its implementation + * interface MountainArray { + * public int get(int index) {} + * public int length() {} + * } + */ + +class Solution { + public int findInMountainArray(int target, MountainArray mountainArr) { + int n = mountainArr.length(); + int start = 1; + int end = n - 2; + while (start != end) { + int mid = (start + end) / 2; + if (mountainArr.get(mid) < mountainArr.get(mid + 1)) { + start = mid + 1; + } else { + end = mid; + } + } + int peakIndex = start; + start = 0; + end = peakIndex; + while (start != end) { + int mid = (start + end) / 2; + if (mountainArr.get(mid) < target) { + start = mid + 1; + } else { + end = mid; + } + } + if (mountainArr.get(start) == target) { + return start; + } + start = peakIndex + 1; + end = n - 1; + while (start != end) { + int mid = (start + end) / 2; + if (mountainArr.get(mid) > target) { + start = mid + 1; + } else { + end = mid; + } + } + return mountainArr.get(start) == target ? start : -1; + } +} diff --git a/Hard/Find the Kth Smallest Sum of a Matrix With Sorted Rows.java b/Hard/Find the Kth Smallest Sum of a Matrix With Sorted Rows.java new file mode 100644 index 00000000..e5800be2 --- /dev/null +++ b/Hard/Find the Kth Smallest Sum of a Matrix With Sorted Rows.java @@ -0,0 +1,19 @@ +class Solution { + public int kthSmallest(int[][] mat, int k) { + PriorityQueue prevSum = new PriorityQueue<>(Collections.reverseOrder()); + prevSum.add(0); + for (int[] row : mat) { + PriorityQueue nextSum = new PriorityQueue<>(Collections.reverseOrder()); + for (int sum : prevSum) { + for (int c = 0; c < mat[0].length; c++) { + nextSum.add(sum + row[c]); + if (nextSum.size() > k) { + nextSum.poll(); + } + } + } + prevSum = nextSum; + } + return prevSum.poll(); + } +} diff --git a/Hard/Find the Longest Valid Obstacle Course at Each Position.java b/Hard/Find the Longest Valid Obstacle Course at Each Position.java new file mode 100644 index 00000000..fcd272fb --- /dev/null +++ b/Hard/Find the Longest Valid Obstacle Course at Each Position.java @@ -0,0 +1,34 @@ +class Solution { + public int[] longestObstacleCourseAtEachPosition(int[] obstacles) { + int n = obstacles.length; + int lisLength = 0; + int[] result = new int[n]; + int[] lis = new int[n]; + for (int i = 0; i < n; i++) { + int height = obstacles[i]; + int idx = bisect(lis, height, lisLength); + if (idx == lisLength) { + lisLength++; + } + lis[idx] = height; + result[i] = idx + 1; + } + return result; + } + + private int bisect(int[] lis, int target, int right) { + if (right == 0) { + return 0; + } + int left = 0; + while (left < right) { + int mid = left + (right - left) / 2; + if (lis[mid] <= target) { + left = mid + 1; + } else { + right = mid; + } + } + return left; + } +} diff --git a/Hard/First Missing Positive.java b/Hard/First Missing Positive.java index 91b5b6fd..3b501319 100644 --- a/Hard/First Missing Positive.java +++ b/Hard/First Missing Positive.java @@ -1,28 +1,27 @@ class Solution { - public int firstMissingPositive(int[] nums) { - int n = nums.length; - int idx = 0; - while (idx < n) { - if (nums[idx] > 0 && nums[idx] < n && nums[nums[idx]] != nums[idx]) { - swap(nums, idx, nums[idx]); - } - else { - idx++; - } + public int firstMissingPositive(int[] nums) { + int n = nums.length; + for (int i = 0; i < n; i++) { + if (nums[i] < 0) { + nums[i] = 0; + } + } + for (int i = 0; i < n; i++) { + int val = Math.abs(nums[i]); + if (val >= 1 && val <= n) { + int idx = val - 1; + if (nums[idx] > 0) { + nums[idx] *= -1; + } else if (nums[idx] == 0) { + nums[idx] = -1 * (n + 1); + } + } + } + for (int i = 1; i <= n; i++) { + if (nums[i - 1] >= 0) { + return i; + } + } + return n + 1; } - idx = 1; - while (idx < n && nums[idx] == idx) { - idx++; - } - if (n == 0 || idx < n) { - return idx; - } - return nums[0] == idx ? idx + 1 : idx; - } - - private void swap(int[] nums, int i, int j) { - int temp = nums[i]; - nums[i] = nums[j]; - nums[j] = temp; - } } diff --git a/Hard/Greatest Common Divisor Traversal.java b/Hard/Greatest Common Divisor Traversal.java new file mode 100644 index 00000000..81ab07de --- /dev/null +++ b/Hard/Greatest Common Divisor Traversal.java @@ -0,0 +1,80 @@ +class Solution { + + private static final int MAX = 100_000; + + public boolean canTraverseAllPairs(int[] nums) { + int n = nums.length; + if (n == 1) { + return true; + } + boolean[] exists = new boolean[MAX + 1]; + for (int num : nums) { + exists[num] = true; + } + if (exists[1]) { + return false; + } + int[] sieve = new int[MAX + 1]; + for (int i = 2; i <= MAX; i++) { + if (sieve[i] == 0) { + for (int j = i; j <= MAX; j += i) { + sieve[j] = i; + } + } + } + Union union = new Union(2 * MAX + 1); + for (int num : nums) { + int curr = num; + while (curr > 1) { + int prime = sieve[curr]; + int root = prime + MAX; + if (union.find(root) != union.find(num)) { + union.merge(root, num); + } + while (curr % prime == 0) { + curr /= prime; + } + } + } + int count = 0; + for (int i = 2; i <= MAX; i++) { + if (exists[i] && union.find(i) == i) { + count++; + } + } + return count == 1; + } + + private class Union { + private final int[] union; + private final int[] size; + + public Union(int n) { + this.union = new int[n + 1]; + this.size = new int[n + 1]; + for (int i = 0; i <= n; i++) { + union[i] = i; + size[i] = 1; + } + } + + public int find(int num) { + return union[num] == num ? num : (union[num] = find(union[num])); + } + + public void merge(int x, int y) { + int findX = find(x); + int findY = find(y); + if (findX == findY) { + return; + } + if (size[findX] > size[findY]) { + int temp = findX; + findX = findY; + findY = temp; + } + union[findX] = findY; + size[findY] += size[findX]; + } + } +} diff --git a/Hard/Height of Binary Tree After Subtree Removal Queries.java b/Hard/Height of Binary Tree After Subtree Removal Queries.java new file mode 100644 index 00000000..ebd9acbe --- /dev/null +++ b/Hard/Height of Binary Tree After Subtree Removal Queries.java @@ -0,0 +1,48 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public int[] treeQueries(TreeNode root, int[] queries) { + Map result = new HashMap<>(); + Map heightCache = new HashMap<>(); + dfs(root, 0, 0, result, heightCache); + int[] answer = new int[queries.length]; + for (int i = 0; i < queries.length; i++) { + answer[i] = result.get(queries[i]); + } + return answer; + } + + private void dfs(TreeNode node, int depth, int maxDepth, Map result, Map heightCache) { + if (node == null) { + return; + } + result.put(node.val, maxDepth); + dfs(node.left, depth + 1, Math.max(maxDepth, depth + 1 + height(node.right, heightCache)), result, heightCache); + dfs(node.right, depth + 1, Math.max(maxDepth, depth + 1 + height(node.left, heightCache)), result, heightCache); + } + + private int height(TreeNode node, Map heightCache) { + if (node == null) { + return -1; + } + if (heightCache.containsKey(node)) { + return heightCache.get(node); + } + int currHeight = 1 + Math.max(height(node.left, heightCache), height(node.right, heightCache)); + heightCache.put(node, currHeight); + return currHeight; + } +} diff --git a/Hard/IPO.java b/Hard/IPO.java new file mode 100644 index 00000000..26cfaac8 --- /dev/null +++ b/Hard/IPO.java @@ -0,0 +1,31 @@ +class Solution { + public int findMaximizedCapital(int k, int w, int[] profits, int[] capital) { + int n = profits.length; + Project[] projects = new Project[n]; + int maximumCapital = w; + for (int i = 0; i < n; i++) { + projects[i] = new Project(capital[i], profits[i]); + } + Arrays.sort(projects); + PriorityQueue pq = new PriorityQueue<>(Collections.reverseOrder()); + int idx = 0; + for (int i = 0; i < k; i++) { + while (idx < n && projects[idx].capital <= maximumCapital) { + pq.add(projects[idx++].profit); + } + if (pq.isEmpty()) { + break; + } + maximumCapital += pq.poll(); + } + return maximumCapital; + } + + private record Project(int capital, int profit) implements Comparable { + + @Override + public int compareTo(Project o) { + return capital - o.capital; + } + } +} diff --git a/Hard/Insert Interval.java b/Hard/Insert Interval.java deleted file mode 100644 index a4b6f9cc..00000000 --- a/Hard/Insert Interval.java +++ /dev/null @@ -1,49 +0,0 @@ -class Solution { - public int[][] insert(int[][] intervals, int[] newInterval) { - List list = new ArrayList<>(); - boolean merged = false; - int idx = 0; - int n = intervals.length; - while (idx < n) { - if (merged) { - list.add(intervals[idx++]); - continue; - } - if (isOverlap(intervals[idx], newInterval)) { - int start = Math.min(intervals[idx][0], newInterval[0]); - int currEnd = Math.max(intervals[idx][1], newInterval[1]); - idx++; - while (idx < n && intervals[idx][0] <= currEnd) { - currEnd = Math.max(currEnd, intervals[idx][1]); - idx++; - } - list.add(new int[]{start, currEnd}); - merged = true; - } - else if (intervals[idx][0] > newInterval[1]) { - list.add(newInterval); - list.add(intervals[idx++]); - merged = true; - } - else { - list.add(intervals[idx++]); - } - } - if (!merged) { - list.add(newInterval); - } - int[][] ans = new int[list.size()][2]; - for (int i = 0; i < list.size(); i++) { - ans[i] = list.get(i); - } - return ans; - } - - private boolean isOverlap(int[] i1, int[] i2) { - return ( - (i2[0] <= i1[1] && i2[0] >= i1[0]) || - (i2[1] >= i1[0] && i2[0] <= i1[0]) || - (i2[0] >= i1[0] && i2[1] <= i1[1]) - ); - } -} diff --git a/Hard/Interleaving String.java b/Hard/Interleaving String.java deleted file mode 100644 index 3fd73eb2..00000000 --- a/Hard/Interleaving String.java +++ /dev/null @@ -1,33 +0,0 @@ -class Solution { - public boolean isInterleave(String s1, String s2, String s3) { - if (s1.length()+s2.length() != s3.length()) { - return false; - } - - boolean[][] dp = new boolean[s1.length()+1][s2.length()+1]; - - dp[0][0] = true; - - for (int i = 0; i <= s1.length(); i++){ - for (int j = 0; j <= s2.length(); j++){ - boolean s1Check = false; - boolean s2Check = false; - - if (i > 0) { - s1Check = dp[i-1][j] && s3.charAt(i+j-1) == s1.charAt(i-1); - } - - if (j > 0) { - s2Check = dp[i][j-1] && s3.charAt(i+j-1) == s2.charAt(j-1); - } - - if (i>0 || j>0) { - dp[i][j] = s1Check || s2Check; - } - } - } - - - return dp[s1.length()][s2.length()]; - } -} diff --git a/Hard/Jump Game IV.java b/Hard/Jump Game IV.java new file mode 100644 index 00000000..960ce4b7 --- /dev/null +++ b/Hard/Jump Game IV.java @@ -0,0 +1,39 @@ +class Solution { + public int minJumps(int[] arr) { + int n = arr.length; + Map> graph = new HashMap<>(); + for (int i = 0; i < n; i++) { + graph.computeIfAbsent(arr[i], k -> new ArrayList<>()).add(i); + } + Queue path = new LinkedList<>(); + Set visited = new HashSet<>(); + path.add(0); + int steps = 0; + while (!path.isEmpty()) { + int size = path.size(); + while (size-- > 0) { + int removed = path.remove(); + if (removed == n - 1) { + return steps; + } + for (Integer child : graph.get(arr[removed])) { + if (!visited.contains(child)) { + visited.add(child); + path.add(child); + } + } + graph.get(arr[removed]).clear(); + if (removed + 1 < n && !visited.contains(removed + 1)) { + visited.add(removed + 1); + path.add(removed + 1); + } + if (removed - 1 >= 0 && !visited.contains(removed - 1)) { + visited.add(removed - 1); + path.add(removed - 1); + } + } + steps++; + } + return -1; + } +} diff --git a/Hard/K Empty Slots.java b/Hard/K Empty Slots.java index 6b004bf0..bb499351 100644 --- a/Hard/K Empty Slots.java +++ b/Hard/K Empty Slots.java @@ -1,19 +1,23 @@ class Solution { - public int kEmptySlots(int[] flowers, int k) { - TreeSet set = new TreeSet<>(); - int day = 0; - - for (int flower : flowers) { - day++; - set.add(flower); - Integer lower = set.lower(flower); - Integer higher = set.higher(flower); - - if ((lower != null && flower - lower - 1 == k) || (higher != null && higher - flower - 1 == k)) { - return day; - } - } - - return -1; + public int kEmptySlots(int[] bulbs, int k) { + int n = bulbs.length; + int[] position = new int[n + 1]; + for (int i = 0; i < n; i++) { + position[bulbs[i]] = i; } + int result = Integer.MAX_VALUE; + int start = 1; + int end = k + 2; + for (int i = 1; end <= n; i++) { + if (position[i] > position[start] && position[i] > position[end]) { + continue; + } + if (i == end) { + result = Math.min(result, Math.max(position[start], position[end]) + 1); + } + start = i; + end = k + 1 + i; + } + return result == Integer.MAX_VALUE ? -1 : result; + } } diff --git a/Hard/K Inverse Pairs Array.java b/Hard/K Inverse Pairs Array.java new file mode 100644 index 00000000..0b6e0d8f --- /dev/null +++ b/Hard/K Inverse Pairs Array.java @@ -0,0 +1,17 @@ +class Solution { + public int kInversePairs(int n, int k) { + int[][] dp = new int[n + 1][k + 1]; + int mod = 1000000007; + for (int i = 1; i <= n; i++) { + for (int j = 0; j <= k; j++) { + if (j == 0) { + dp[i][j] = 1; + } else { + int curr = (dp[i - 1][j] + mod - ((j - i) >= 0 ? dp[i - 1][j - i] : 0)) % mod; + dp[i][j] = (dp[i][j - 1] + curr) % mod; + } + } + } + return ((dp[n][k] + mod - (k > 0 ? dp[n][k - 1] : 0)) % mod); + } +} diff --git a/Hard/K-th Smallest in Lexicographical Order.java b/Hard/K-th Smallest in Lexicographical Order.java new file mode 100644 index 00000000..9063cd56 --- /dev/null +++ b/Hard/K-th Smallest in Lexicographical Order.java @@ -0,0 +1,27 @@ +class Solution { + public int findKthNumber(int n, int k) { + int curr = 1; + k--; + while (k > 0) { + int count = countNumsWithPrefix(n, curr, curr + 1); + if (count <= k) { + curr++; + k -= count; + } else { + curr *= 10; + k--; + } + } + return curr; + } + + private int countNumsWithPrefix(int n, long start, long end) { + int count = 0; + while (start <= n) { + count += Math.min(n + 1, end) - start; + start *= 10; + end *= 10; + } + return count; + } +} diff --git a/Hard/Kth Smallest Number in Multiplication Table.java b/Hard/Kth Smallest Number in Multiplication Table.java new file mode 100644 index 00000000..84d55bf2 --- /dev/null +++ b/Hard/Kth Smallest Number in Multiplication Table.java @@ -0,0 +1,19 @@ +class Solution { + public int findKthNumber(int m, int n, int k) { + int low = 0; + int high = m * n; + while (low < high) { + int mid = (low + high) / 2; + int count = 0; + for (int i = 1; i <= m; i++) { + count += Math.min(n, mid / i); + } + if (count >= k) { + high = mid; + } else { + low = mid + 1; + } + } + return low; + } +} diff --git a/Hard/LFU Cache.java b/Hard/LFU Cache.java index 588f7a60..d4caef70 100644 --- a/Hard/LFU Cache.java +++ b/Hard/LFU Cache.java @@ -1,75 +1,122 @@ class LFUCache { - private Map valMap; - private Map freqMap; - private Map> freqCountMap; - private int capacity; - private int minValue; + private final TreeMap frequencyToNodeMap; + private final Map keyToNodeMap; + private final int capacity; public LFUCache(int capacity) { - valMap = new HashMap<>(); - freqMap = new HashMap<>(); - freqCountMap = new HashMap<>(); + this.frequencyToNodeMap = new TreeMap<>(); + this.keyToNodeMap = new HashMap<>(); this.capacity = capacity; - minValue = 0; } public int get(int key) { - if (!valMap.containsKey(key)) { + if (!keyToNodeMap.containsKey(key)) { return -1; } + Node node = keyToNodeMap.get(key); + updateNodeForFrequencyChange(node); + return node.value; + } - // Updating frequency - int oldFreq = freqMap.get(key); - freqMap.put(key, oldFreq + 1); - int newFreq = freqMap.get(key); - - // Removing from old frequency set - LinkedHashSet set = freqCountMap.get(oldFreq); - set.remove(key); - if (set.isEmpty()) { - // As this was the only key with min freq so minimum frequency should be updated - if (minValue == oldFreq) { - minValue = oldFreq + 1; - } - freqCountMap.remove(oldFreq); - } - else { - freqCountMap.put(oldFreq, set); + public void put(int key, int value) { + if (this.keyToNodeMap.containsKey(key)) { + updateNode(key, value); + } else { + addNewNode(key, value); } + } - // Updating new frequency set - freqCountMap.computeIfAbsent(newFreq, k -> new LinkedHashSet<>()).add(key); - - return valMap.get(key); + private void updateNode(int key, int value) { + Node node = keyToNodeMap.get(key); + node.value = value; + updateNodeForFrequencyChange(node); } - public void put(int key, int value) { + private void addNewNode(int key, int value) { if (capacity == 0) { return; } - - if (get(key) != -1) { - valMap.put(key, value); - return; + if (capacity == keyToNodeMap.size()) { + evictCache(); + } + Node node = new Node(key, value); + addToFrequencyMap(node); + keyToNodeMap.put(key, node); + } + + private void evictCache() { + int firstKey = frequencyToNodeMap.firstKey(); + Node nodeToEvict = frequencyToNodeMap.get(firstKey).getFirstNode(); + removeNode(nodeToEvict); + keyToNodeMap.remove(nodeToEvict.key); + if (frequencyToNodeMap.get(firstKey).getFirstNode().value == -1) { + frequencyToNodeMap.remove(firstKey); + } + } + + private void updateNodeForFrequencyChange(Node node) { + int prevFrequency = node.frequency; + node.frequency = node.frequency + 1; + removeNode(node); + if (frequencyToNodeMap.get(prevFrequency).getFirstNode().value == -1) { + frequencyToNodeMap.remove(prevFrequency); } + addToFrequencyMap(node); + } - if (valMap.size() == capacity) { - LinkedHashSet set = freqCountMap.get(minValue); - int keyToBeDeleted = set.iterator().next(); - valMap.remove(keyToBeDeleted); - freqMap.remove(keyToBeDeleted); - set.remove(keyToBeDeleted); + private void removeNode(Node node) { + Node prevToNode = node.prev; + Node nextToNode = node.next; + prevToNode.next = nextToNode; + nextToNode.prev = prevToNode; + } - if (set.isEmpty()) { - freqCountMap.remove(minValue); - } + private void addToFrequencyMap(Node node) { + if (!frequencyToNodeMap.containsKey(node.frequency)) { + frequencyToNodeMap.put(node.frequency, new NodeLinkedList()); } + frequencyToNodeMap.get(node.frequency).addNode(node); + } + + private static class NodeLinkedList { + private final Node head; + private final Node tail; - valMap.put(key, value); - freqMap.put(key, 1); - freqCountMap.computeIfAbsent(1, k -> new LinkedHashSet<>()).add(key); - minValue = 1; + public NodeLinkedList() { + this.head = new Node(-1, -1); + this.tail = new Node(-1, -1); + head.next = tail; + tail.prev = head; + } + + public Node getFirstNode() { + return head.next; + } + + public void addNode(Node node) { + Node prevToTail = tail.prev; + node.prev = prevToTail; + prevToTail.next = node; + node.next = tail; + tail.prev = node; + } + } + + private static class Node { + private final int key; + private int value; + private int frequency; + private Node next; + private Node prev; + + public Node(int key, int value) { + this.key = key; + this.value = value; + this.frequency = 1; + this.next = null; + this.prev = null; + } } } diff --git a/Hard/LRU Cache.java b/Hard/LRU Cache.java deleted file mode 100644 index 2f2c70c0..00000000 --- a/Hard/LRU Cache.java +++ /dev/null @@ -1,79 +0,0 @@ -class LRUCache { - Node head; - Node tail; - Map map; - int capacity; - public LRUCache(int capacity) { - head = new Node(-1, -1); - tail = new Node(-1, -1); - head.next = tail; - tail.prev = head; - map = new HashMap<>(); - this.capacity = capacity; - } - - public int get(int key) { - if (!map.containsKey(key)) { - return -1; - } - int val = map.get(key).val; - moveToFront(map.get(key)); - return val; - } - - public void put(int key, int value) { - if (!map.containsKey(key)) { - if (map.size() == capacity) { - evictKey(tail.prev); - } - Node node = new Node(key, value); - map.put(key, node); - node.next = head.next; - head.next.prev = node; - head.next = node; - node.prev = head; - } - else { - map.get(key).val = value; - moveToFront(map.get(key)); - } - } - - private void moveToFront(Node node) { - Node prev = node.prev; - node.next.prev = prev; - prev.next = node.next; - node.next = head.next; - head.next.prev = node; - node.prev = head; - head.next = node; - } - - private void evictKey(Node node) { - Node prev = node.prev; - node.next.prev = prev; - prev.next = node.next; - map.remove(node.key); - } -} - -/** - * Your LRUCache object will be instantiated and called as such: - * LRUCache obj = new LRUCache(capacity); - * int param_1 = obj.get(key); - * obj.put(key,value); - */ - -class Node { - int key; - int val; - Node next; - Node prev; - - public Node(int key, int val) { - this.key = key; - this.val = val; - next = null; - prev = null; - } -} diff --git a/Hard/Largest Color Value in a Directed Graph.java b/Hard/Largest Color Value in a Directed Graph.java new file mode 100644 index 00000000..2d2fe6d5 --- /dev/null +++ b/Hard/Largest Color Value in a Directed Graph.java @@ -0,0 +1,39 @@ +class Solution { + public int largestPathValue(String colors, int[][] edges) { + int n = colors.length(); + Map> graph = new HashMap<>(); + int[] indegree = new int[n]; + for (int[] edge : edges) { + graph.computeIfAbsent(edge[0], k -> new ArrayList<>()) + .add(edge[1]); + indegree[edge[1]]++; + } + int[][] count = new int[n][26]; + Queue queue = new LinkedList<>(); + for (int i = 0; i < n; i++) { + if (indegree[i] == 0) { + queue.add(i); + } + } + int result = 1; + int seen = 0; + while (!queue.isEmpty()) { + int node = queue.remove(); + result = Math.max(result, ++count[node][colors.charAt(node) - 'a']); + seen++; + if (!graph.containsKey(node)) { + continue; + } + for (int neighbor : graph.get(node)) { + for (int i = 0; i < 26; i++) { + count[neighbor][i] = Math.max(count[neighbor][i], count[node][i]); + } + indegree[neighbor]--; + if (indegree[neighbor] == 0) { + queue.add(neighbor); + } + } + } + return seen < n ? -1 : result; + } +} diff --git a/Hard/Longest Consecutive Sequence.java b/Hard/Longest Consecutive Sequence.java deleted file mode 100644 index 9ba20263..00000000 --- a/Hard/Longest Consecutive Sequence.java +++ /dev/null @@ -1,27 +0,0 @@ -class Solution { - public int longestConsecutive(int[] nums) { - Set set = new HashSet<>(); - for (int num : nums) { - set.add(num); - } - - int maxLen = 0; - Iterator iterator = set.iterator(); - while (iterator.hasNext()) { - int num = iterator.next(); - if (!set.contains(num - 1)) { - int current = num; - int currLen = 1; - - while (set.contains(current + 1)) { - current += 1; - currLen++; - } - - maxLen = Math.max(maxLen, currLen); - } - } - - return maxLen; - } -} diff --git a/Hard/Longest Cycle in a Graph.java b/Hard/Longest Cycle in a Graph.java new file mode 100644 index 00000000..6405e016 --- /dev/null +++ b/Hard/Longest Cycle in a Graph.java @@ -0,0 +1,26 @@ +class Solution { + public int longestCycle(int[] edges) { + int n = edges.length; + boolean[] visited = new boolean[n]; + int[] result = {-1}; + for (int i = 0; i < n; i++) { + if (!visited[i]) { + Map map = new HashMap<>(); + map.put(i, 1); + dfs(i, edges, map, visited, result); + } + } + return result[0]; + } + + private void dfs(int node, int[] edges, Map map, boolean[] visited, int[] result) { + visited[node] = true; + int neighbor = edges[node]; + if (neighbor != -1 && !visited[neighbor]) { + map.put(neighbor, map.get(node) + 1); + dfs(neighbor, edges, map, visited, result); + } else if (neighbor != -1 && map.containsKey(neighbor)) { + result[0] = Math.max(result[0], map.get(node) - map.get(neighbor) + 1); + } + } +} diff --git a/Hard/Longest Increasing Path in a Matrix.java b/Hard/Longest Increasing Path in a Matrix.java index 6ba938a2..e7c7f819 100644 --- a/Hard/Longest Increasing Path in a Matrix.java +++ b/Hard/Longest Increasing Path in a Matrix.java @@ -1,36 +1,30 @@ class Solution { - int[][] dirs = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; - public int longestIncreasingPath(int[][] matrix) { - if (matrix.length == 0 || matrix[0].length == 0) { - return 0; - } - - int[][] dp = new int[matrix.length][matrix[0].length]; - int max = 0; - for (int i = 0; i < matrix.length; i++) { - for (int j = 0; j < matrix[0].length; j++) { - max = Math.max(max, dfs(matrix, i, j, dp, Integer.MIN_VALUE)); - } - } - - return max; + private final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + + public int longestIncreasingPath(int[][] matrix) { + int numRows = matrix.length; + int numCols = matrix[0].length; + int maxPathLength = 0; + int[][] cache = new int[numRows][numCols]; + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numCols; j++) { + maxPathLength = Math.max(maxPathLength, helper(matrix, numRows, numCols, i, j, cache)); + } } - - private int dfs(int[][] matrix, int x, int y, int[][] dp, int prevVal) { - if (x < 0 || x >= matrix.length || y < 0 || y >= matrix[0].length || matrix[x][y] <= prevVal) { - return 0; - } - - if (dp[x][y] != 0) { - return dp[x][y]; - } - - int temp = 0; - for (int[] dir : dirs) { - temp = Math.max(temp, dfs(matrix, x + dir[0], y + dir[1], dp, matrix[x][y])); - } - - dp[x][y] = temp + 1; - return dp[x][y]; + return maxPathLength; + } + + private int helper(int[][] matrix, int numRows, int numCols, int i, int j, int[][] cache) { + if (cache[i][j] != 0) { + return cache[i][j]; } + for (int[] dir : DIRS) { + int x = i + dir[0]; + int y = j + dir[1]; + if (x >= 0 && y >= 0 && x < numRows && y < numCols && matrix[x][y] > matrix[i][j]) { + cache[i][j] = Math.max(cache[i][j], helper(matrix, numRows, numCols, x, y, cache)); + } + } + return ++cache[i][j]; + } } diff --git a/Hard/Longest Substring with At Most K Distinct Characters.java b/Hard/Longest Substring with At Most K Distinct Characters.java deleted file mode 100644 index ae6a1c78..00000000 --- a/Hard/Longest Substring with At Most K Distinct Characters.java +++ /dev/null @@ -1,22 +0,0 @@ -class Solution { - public int lengthOfLongestSubstringKDistinct(String s, int k) { - Map map = new HashMap<>(); - int slow = 0; - int fast = 0; - int n = s.length(); - int maxLength = 0; - while (fast < n) { - map.put(s.charAt(fast), map.getOrDefault(s.charAt(fast), 0) + 1); - while (map.size() > k) { - map.put(s.charAt(slow), map.getOrDefault(s.charAt(slow), 0) - 1); - if (map.get(s.charAt(slow)) == 0) { - map.remove(s.charAt(slow)); - } - slow++; - } - fast++; - maxLength = Math.max(maxLength, fast - slow); - } - return maxLength; - } -} diff --git a/Hard/Longest Substring with At Most Two Distinct Characters.java b/Hard/Longest Substring with At Most Two Distinct Characters.java deleted file mode 100644 index deb1b3d7..00000000 --- a/Hard/Longest Substring with At Most Two Distinct Characters.java +++ /dev/null @@ -1,27 +0,0 @@ -class Solution { - public int lengthOfLongestSubstringTwoDistinct(String s) { - Map map = new HashMap<>(); - int slow = 0; - int fast = 0; - int maxLen = 0; - int n = s.length(); - - while (fast < n) { - map.put(s.charAt(fast), map.getOrDefault(s.charAt(fast), 0) + 1); - - while (map.size() > 2) { - map.put(s.charAt(slow), map.getOrDefault(s.charAt(slow), 0) - 1); - if (map.get(s.charAt(slow)) <= 0) { - map.remove(s.charAt(slow)); - } - - slow++; - } - - fast++; - maxLen = Math.max(maxLen, fast - slow); - } - - return maxLen; - } -} diff --git a/Hard/Longest Valid Parentheses.java b/Hard/Longest Valid Parentheses.java new file mode 100644 index 00000000..5f0d934c --- /dev/null +++ b/Hard/Longest Valid Parentheses.java @@ -0,0 +1,34 @@ +class Solution { + public int longestValidParentheses(String s) { + int maxLength = 0; + int leftIdx = 0; + int rightIdx = 0; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '(') { + leftIdx++; + } else { + rightIdx++; + } + if (leftIdx == rightIdx) { + maxLength = Math.max(maxLength, 2 * rightIdx); + } else if (rightIdx > leftIdx) { + leftIdx = rightIdx = 0; + } + } + leftIdx = 0; + rightIdx = 0; + for (int i = s.length() - 1; i >= 0; i--) { + if (s.charAt(i) == '(') { + leftIdx++; + } else { + rightIdx++; + } + if (leftIdx == rightIdx) { + maxLength = Math.max(maxLength, 2 * rightIdx); + } else if (leftIdx > rightIdx) { + leftIdx = rightIdx = 0; + } + } + return maxLength; + } +} diff --git a/Hard/Make Array Strictly Increasing.java b/Hard/Make Array Strictly Increasing.java new file mode 100644 index 00000000..77bed2a8 --- /dev/null +++ b/Hard/Make Array Strictly Increasing.java @@ -0,0 +1,41 @@ +class Solution { + public int makeArrayIncreasing(int[] arr1, int[] arr2) { + Arrays.sort(arr2); + Map, Integer> dp = new HashMap<>(); + int result = dfs(0, -1, arr1, arr2, dp); + return result < 2001 ? result : -1; + } + + private int dfs(int idx, int prev, int[] arr1, int[] arr2, Map, Integer> dp) { + if (idx == arr1.length) { + return 0; + } + if (dp.containsKey(new Pair<>(idx, prev))) { + return dp.get(new Pair<>(idx, prev)); + } + int cost = 2001; + if (arr1[idx] > prev) { + cost = dfs(idx + 1, arr1[idx], arr1, arr2, dp); + } + int replaceIdx = binarySearch(arr2, prev); + if (replaceIdx < arr2.length) { + cost = Math.min(cost, 1 + dfs(idx + 1, arr2[replaceIdx], arr1, arr2, dp)); + } + dp.put(new Pair<>(idx, prev), cost); + return cost; + } + + private static int binarySearch(int[] arr, int value) { + int left = 0; + int right = arr.length; + while (left < right) { + int mid = (left + right) / 2; + if (arr[mid] <= value) { + left = mid + 1; + } else { + right = mid; + } + } + return left; + } +} diff --git a/Hard/Making A Large Island.java b/Hard/Making A Large Island.java new file mode 100644 index 00000000..d1026bd7 --- /dev/null +++ b/Hard/Making A Large Island.java @@ -0,0 +1,68 @@ +class Solution { + + private static final int[][] DIRS = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}}; + + public int largestIsland(int[][] grid) { + int n = grid.length; + int tag = 2; + int result = 0; + Map tagToAreaMapping = new HashMap<>(); + // Calculate area without changing 0 to 1 & tag each island for future reference + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 1) { + tagToAreaMapping.put(tag, dfs(grid, i, j, tag)); + result = Math.max(result, tagToAreaMapping.get(tag)); + tag++; + } + } + } + // Now start changing each 0 to 1 & add the area of all connected islands by referencing their tags + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 0) { + Set visited = new HashSet<>(); + int currArea = 1; + List moves = getMoves(i, j, n); + for (int[] move : moves) { + int x = move[0]; + int y = move[1]; + int currTag = grid[x][y]; + if (currTag > 1 && visited.add(currTag)) { + currArea += tagToAreaMapping.get(currTag); + } + } + result = Math.max(result, currArea); + } + } + } + return result; + } + + private int dfs(int[][] grid, int x, int y, int tag) { + int area = 1; + int n = grid.length; + grid[x][y] = tag; + List moves = getMoves(x, y, n); + for (int[] move : moves) { + int i = move[0]; + int j = move[1]; + if (grid[i][j] == 1) { + area += dfs(grid, i, j, tag); + } + } + return area; + } + + private List getMoves(int x, int y, int n) { + List moves = new ArrayList<>(); + for (int[] dir : DIRS) { + int newX = x + dir[0]; + int newY = y + dir[1]; + if (newX >= 0 && newX < n && newY >= 0 && newY < n) { + moves.add(new int[]{newX, newY}); + } + } + return moves; + } +} diff --git a/Hard/Max Dot Product of Two Subsequences.java b/Hard/Max Dot Product of Two Subsequences.java new file mode 100644 index 00000000..c2eca127 --- /dev/null +++ b/Hard/Max Dot Product of Two Subsequences.java @@ -0,0 +1,30 @@ +class Solution { + public int maxDotProduct(int[] nums1, int[] nums2) { + int maxOne = Integer.MIN_VALUE; + int maxTwo = Integer.MIN_VALUE; + int minOne = Integer.MAX_VALUE; + int minTwo = Integer.MAX_VALUE; + for (int num : nums1) { + maxOne = Math.max(maxOne, num); + minOne = Math.min(minOne, num); + } + for (int num : nums2) { + maxTwo = Math.max(maxTwo, num); + minTwo = Math.min(minTwo, num); + } + if (maxOne < 0 && minTwo > 0) { + return maxOne * minTwo; + } + if (minOne > 0 && maxTwo < 0) { + return minOne * maxTwo; + } + int[][] dp = new int[nums1.length + 1][nums2.length + 1]; + for (int i = nums1.length - 1; i >= 0; i--) { + for (int j = nums2.length - 1; j >= 0; j--) { + int curr = nums1[i] * nums2[j] + dp[i + 1][j + 1]; + dp[i][j] = Math.max(curr, Math.max(dp[i + 1][j], dp[i][j + 1])); + } + } + return dp[0][0]; + } +} diff --git a/Hard/Max Points on a Line.java b/Hard/Max Points on a Line.java new file mode 100644 index 00000000..7368488e --- /dev/null +++ b/Hard/Max Points on a Line.java @@ -0,0 +1,26 @@ +class Solution { + public int maxPoints(int[][] points) { + int max = 0; + for (int i = 0; i < points.length - 1; i++) { + Map map = new HashMap<>(); + for (int j = i + 1; j < points.length; j++) { + double slope = calculateSlope(points[i], points[j]); + map.put(slope, map.getOrDefault(slope, 0) + 1); + max = Math.max(max, map.get(slope)); + } + } + return max + 1; + } + + private double calculateSlope(int[] p1, int[] p2) { + double y = (p2[1] - p1[1]) * 1.0; + double x = (p2[0] - p1[0]) * 1.0; + if (x == 0) { + return Double.NaN; + } + if(y == 0) { + return 0.0; + } + return ((double) y * 1.0) / x; + } +} diff --git a/Hard/Max Stack.java b/Hard/Max Stack.java new file mode 100644 index 00000000..918b74b5 --- /dev/null +++ b/Hard/Max Stack.java @@ -0,0 +1,85 @@ +class MaxStack { + + private TreeMap> map; + private Node head; + private Node tail; + + public MaxStack() { + this.map = new TreeMap<>(); + this.head = new Node(-1); + this.tail = new Node(-1); + this.head.next = this.tail; + this.tail.prev = this.head; + } + + public void push(int x) { + Node node = createNode(x); + map.computeIfAbsent(x, k -> new Stack<>()).push(node); + } + + private Node createNode(int x) { + Node node = new Node(x); + Node prevToTail = tail.prev; + node.next = tail; + tail.prev = node; + prevToTail.next = node; + node.prev = prevToTail; + return node; + } + + public int pop() { + Node toRemove = tail.prev; + int val = toRemove.val; + map.get(val).pop(); + if (map.get(val).isEmpty()) { + map.remove(val); + } + removeNode(toRemove); + return toRemove.val; + } + + public int top() { + return tail.prev.val; + } + + public int peekMax() { + return map.lastKey(); + } + + public int popMax() { + int val = map.lastKey(); + Node node = map.get(val).pop(); + if (map.get(val).isEmpty()) { + map.remove(val); + } + removeNode(node); + return val; + } + + private void removeNode(Node node) { + Node prevNode = node.prev; + Node nextNode = node.next; + prevNode.next = nextNode; + nextNode.prev = prevNode; + } + + private static class Node { + Node next; + Node prev; + int val; + + public Node(int val) { + this.val = val; + } + } +} + +/** + * Your MaxStack object will be instantiated and called as such: + * MaxStack obj = new MaxStack(); + * obj.push(x); + * int param_2 = obj.pop(); + * int param_3 = obj.top(); + * int param_4 = obj.peekMax(); + * int param_5 = obj.popMax(); + */ diff --git a/Hard/Maximize Score After N Operations.java b/Hard/Maximize Score After N Operations.java new file mode 100644 index 00000000..2ed4f892 --- /dev/null +++ b/Hard/Maximize Score After N Operations.java @@ -0,0 +1,37 @@ +class Solution { + public int maxScore(int[] nums) { + int dpSize = 1 << nums.length; + int[] dp = new int[dpSize]; + Arrays.fill(dp, -1); + return backtrack(nums, 0, 0, dp); + } + + private int backtrack(int[] nums, int mask, int pickCount, int[] dp) { + if (2 * pickCount == nums.length) { + return 0; + } + if (dp[mask] != -1) { + return dp[mask]; + } + int maxScore = 0; + for (int i = 0; i < nums.length; i++) { + for (int j = i + 1; j < nums.length; j++) { + if (((mask >> i) & 1) == 1 || ((mask >> j) & 1) == 1) { + continue; + } + int newMask = mask | (1 << i) | (1 << j); + int curr = (pickCount + 1) * gcd(nums[i], nums[j]); + int remaining = backtrack(nums, newMask, pickCount + 1, dp); + maxScore = Math.max(maxScore, curr + remaining); + } + } + return dp[mask] = maxScore; + } + + private int gcd(int a, int b) { + if (b == 0) { + return a; + } + return gcd(b, a % b); + } +} diff --git a/Hard/Maximum Frequency Stack.java b/Hard/Maximum Frequency Stack.java index 726b5651..a638cede 100644 --- a/Hard/Maximum Frequency Stack.java +++ b/Hard/Maximum Frequency Stack.java @@ -1,26 +1,35 @@ class FreqStack { - Map map; - Map> freqMap; - int maxFreq; - public FreqStack() { - freqMap = new HashMap<>(); - map = new HashMap<>(); - maxFreq = Integer.MIN_VALUE; - } - - public void push(int x) { - map.put(x, map.getOrDefault(x, 0) + 1); - maxFreq = Math.max(maxFreq, map.get(x)); - freqMap.computeIfAbsent(map.get(x), k -> new Stack<>()).push(x); - } + + private Map frequencyMap; + private Map> frequencyGroup; + private int maxFrequency; + + public FreqStack() { + this.frequencyMap = new HashMap<>(); + this.frequencyGroup = new HashMap<>(); + this.maxFrequency = 0; + } - public int pop() { - int popped = freqMap.get(maxFreq).pop(); - map.put(popped, map.get(popped) - 1); - if (freqMap.get(maxFreq).size() == 0) { - maxFreq--; - } + public void push(int val) { + int newFrequency = this.frequencyMap.getOrDefault(val, 0) + 1; + this.frequencyMap.put(val, newFrequency); + this.maxFrequency = Math.max(this.maxFrequency, newFrequency); + this.frequencyGroup.computeIfAbsent(newFrequency, k -> new Stack<>()).push(val); + } - return popped; + public int pop() { + int val = this.frequencyGroup.get(this.maxFrequency).pop(); + this.frequencyMap.put(val, this.frequencyMap.get(val) - 1); + if (this.frequencyGroup.get(this.maxFrequency).isEmpty()) { + this.maxFrequency--; } + return val; + } } + +/** + * Your FreqStack object will be instantiated and called as such: + * FreqStack obj = new FreqStack(); + * obj.push(val); + * int param_2 = obj.pop(); + */ diff --git a/Hard/Maximum Performance of a Team.java b/Hard/Maximum Performance of a Team.java new file mode 100644 index 00000000..11a444da --- /dev/null +++ b/Hard/Maximum Performance of a Team.java @@ -0,0 +1,26 @@ +class Solution { + + private final static int MOD = (int) Math.pow(10, 9) + 7; + + public int maxPerformance(int n, int[] speed, int[] efficiency, int k) { + List pairs = new ArrayList<>(); + for (int i = 0; i < n; ++i) { + pairs.add(new int[]{efficiency[i], speed[i]}); + } + Collections.sort(pairs, (o1, o2) -> o2[0] - o1[0]); + PriorityQueue speedMinHeap = new PriorityQueue<>(); + long speedSum = 0; + long performance = 0; + for (int[] pair : pairs) { + Integer currEfficiency = pair[0]; + Integer currSpeed = pair[1]; + if (speedMinHeap.size() > k - 1) { + speedSum -= speedMinHeap.remove(); + } + speedMinHeap.add(currSpeed); + speedSum += currSpeed; + performance = Math.max(performance, speedSum * currEfficiency); + } + return (int) (performance % MOD); + } +} diff --git a/Hard/Maximum Profit in Job Scheduling.java b/Hard/Maximum Profit in Job Scheduling.java new file mode 100644 index 00000000..8a785d43 --- /dev/null +++ b/Hard/Maximum Profit in Job Scheduling.java @@ -0,0 +1,46 @@ +class Solution { + public int jobScheduling(int[] startTime, int[] endTime, int[] profit) { + int n = profit.length; + int[][] jobs = new int[n][3]; + for (int i = 0; i < n; i++) { + jobs[i] = new int[]{startTime[i], endTime[i], profit[i]}; + } + Arrays.sort(jobs, (a, b) -> a[0] - b[0]); + for (int i = 0; i < n; i++) { + startTime[i] = jobs[i][0]; + } + int[] dp = new int[n + 1]; + Arrays.fill(dp, -1); + return findMaxProfit(jobs, startTime, 0, n, dp); + } + + private int findMaxProfit(int[][] jobs, int[] startTime, int position, int n, int[] dp) { + if (position == n) { + return 0; + } + if (dp[position] != -1) { + return dp[position]; + } + int nextPosition = binarySearch(startTime, jobs[position][1]); + return dp[position] = Math.max( + findMaxProfit(jobs, startTime, position + 1, n, dp), // skip executing current job + jobs[position][2] + findMaxProfit(jobs, startTime, nextPosition, n, dp) // execute current job & move to next position + ); + } + + private static int binarySearch(int[] startTime, int endTime) { + int left = 0; + int right = startTime.length - 1; + int nextPosition = startTime.length; + while (left <= right) { + int mid = (left + right) / 2; + if (startTime[mid] >= endTime) { + nextPosition = mid; + right = mid - 1; + } else { + left = mid + 1; + } + } + return nextPosition; + } +} diff --git a/Hard/Maximum Value of K Coins From Piles.java b/Hard/Maximum Value of K Coins From Piles.java new file mode 100644 index 00000000..08fbc802 --- /dev/null +++ b/Hard/Maximum Value of K Coins From Piles.java @@ -0,0 +1,20 @@ +class Solution { + public int maxValueOfCoins(List> piles, int k) { + int n = piles.size(); + int[][] dp = new int[n + 1][k + 1]; + for (int i = 1; i <= n; i++) { + for (int coins = 0; coins <= k; coins++) { + int currSum = 0; + for (int currCoins = 0; + currCoins <= Math.min((int) piles.get(i - 1).size(), coins); + currCoins++) { + if (currCoins > 0) { + currSum += piles.get(i - 1).get(currCoins - 1); + } + dp[i][coins] = Math.max(dp[i][coins], dp[i - 1][coins - currCoins] + currSum); + } + } + } + return dp[n][k]; + } +} diff --git a/Hard/Median of Two Sorted Arrays.java b/Hard/Median of Two Sorted Arrays.java index 375c07fa..33ec700b 100644 --- a/Hard/Median of Two Sorted Arrays.java +++ b/Hard/Median of Two Sorted Arrays.java @@ -1,42 +1,25 @@ class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { - int n = nums1.length + nums2.length; - ArrayList arr = new ArrayList<>(); - - int i = 0; - int j = 0; - int k = 0; - int limit = (n)/2 + 1; - - while (i < nums1.length && j < nums2.length && k < limit) { - if (nums1[i] < nums2[j]) { - arr.add(nums1[i]); - i++; - } - else { - arr.add(nums2[j]); - j++; - } - k++; - } - - if (i < nums1.length) { - while (i < nums1.length && k < limit) { - arr.add(nums1[i]); - i++; - k++; - } + if (nums1.length < nums2.length) { + return findMedianSortedArrays(nums2, nums1); } - else { - while (j < nums2.length && k < limit) { - arr.add (nums2[j]); - j++; - k++; + int low = 0; + int high = nums2.length * 2; + while (low <= high) { + int midTwo = (low + high) / 2; + int midOne = nums1.length + nums2.length - midTwo; + double leftOne = (midOne == 0) ? Integer.MIN_VALUE : nums1[(midOne - 1) / 2]; + double leftTwo = (midTwo == 0) ? Integer.MIN_VALUE : nums2[(midTwo - 1) / 2]; + double rightOne = (midOne == nums1.length * 2) ? Integer.MAX_VALUE : nums1[(midOne) / 2]; + double rightTwo = (midTwo == nums2.length * 2) ? Integer.MAX_VALUE : nums2[(midTwo) / 2]; + if (leftOne > rightTwo) { + low = midTwo + 1; + } else if (leftTwo > rightOne) { + high = midTwo - 1; + } else { + return (Math.max(leftOne, leftTwo) + Math.min(rightOne, rightTwo)) / 2; } } - - k--; - - return n%2 == 0 ? (double) (arr.get(k - 1) + arr.get(k)) / 2.0 : (double) arr.get(k); + return -1; } } diff --git a/Hard/Meeting Rooms III.java b/Hard/Meeting Rooms III.java new file mode 100644 index 00000000..48167f8c --- /dev/null +++ b/Hard/Meeting Rooms III.java @@ -0,0 +1,31 @@ +class Solution { + public int mostBooked(int n, int[][] meetings) { + Arrays.sort(meetings, Comparator.comparingInt(o -> o[0])); + PriorityQueue ongoingMeetings = new PriorityQueue<>(Comparator.comparingInt(a -> a[0])); + int[] frequency = new int[n]; + PriorityQueue pq = new PriorityQueue<>((o1, o2) -> o1[0] == o2[0] ? (int) (o1[1] - o2[1]) : (int) (o1[0] - o2[0])); + for (int i = 0; i < n; i++) { + pq.add(new long[]{0, i}); + } + for (int[] meeting : meetings) { + int startTime = meeting[0]; + while (pq.peek()[0] < startTime) { + pq.add(new long[]{startTime, pq.poll()[1]}); + } + long[] finishedMeeting = pq.poll(); + int room = (int) finishedMeeting[1]; + long endTime = finishedMeeting[0] + (meeting[1] - meeting[0]); + frequency[room]++; + pq.add(new long[]{endTime, room}); + } + int maxCount = 0; + int roomWithMaxCount = 0; + for (int i = 0; i < n; i++) { + if (frequency[i] > maxCount) { + maxCount = frequency[i]; + roomWithMaxCount = i; + } + } + return roomWithMaxCount; + } +} diff --git a/Hard/Merge K Sorted Lists.java b/Hard/Merge K Sorted Lists.java index 7f225ffc..df8ddc91 100644 --- a/Hard/Merge K Sorted Lists.java +++ b/Hard/Merge K Sorted Lists.java @@ -3,41 +3,29 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { - public ListNode mergeKLists(ListNode[] lists) { - if (lists.length == 0) { - return null; - } - - PriorityQueue queue = new PriorityQueue<>(lists.length, new Comparator() { - @Override - public int compare(ListNode o1, ListNode o2) { - return o1.val - o2.val; - } - }); - - for (int i = 0; i < lists.length; i++) { - if (lists[i] != null) { - queue.add(lists[i]); - } - } - - ListNode head = new ListNode(0); - ListNode p = head; - - while (!queue.isEmpty()) { - ListNode node = queue.poll(); - p.next = node; - if (node.next != null) { - queue.add(node.next); - } - - p = p.next; - } - - return head.next; + public ListNode mergeKLists(ListNode[] lists) { + PriorityQueue pq = new PriorityQueue<>((a, b) -> a.val - b.val); + for (ListNode listNode : lists) { + if (listNode != null) { + pq.add(listNode); + } } + ListNode dummy = new ListNode(0); + ListNode curr = dummy; + while (!pq.isEmpty()) { + ListNode removed = pq.remove(); + curr.next = new ListNode(removed.val); + curr = curr.next; + if (removed.next != null) { + pq.add(removed.next); + } + } + return dummy.next; + } } diff --git a/Hard/Minimize Deviation in Array.java b/Hard/Minimize Deviation in Array.java new file mode 100644 index 00000000..905621e6 --- /dev/null +++ b/Hard/Minimize Deviation in Array.java @@ -0,0 +1,21 @@ +class Solution { + public int minimumDeviation(int[] nums) { + int currMinimum = Integer.MAX_VALUE; + PriorityQueue pq = new PriorityQueue<>(Collections.reverseOrder()); + for (int num : nums) { + if (num % 2 != 0) { + num *= 2; + } + currMinimum = Math.min(currMinimum, num); + pq.add(num); + } + int deviation = Integer.MAX_VALUE; + while (pq.peek() % 2 == 0) { + int removed = pq.poll() / 2; + currMinimum = Math.min(currMinimum, removed); + pq.add(removed); + deviation = Math.min(deviation, pq.peek() - currMinimum); + } + return deviation; + } +} diff --git a/Hard/Minimum Cost to Make Array Equal.java b/Hard/Minimum Cost to Make Array Equal.java new file mode 100644 index 00000000..9fe9b8f9 --- /dev/null +++ b/Hard/Minimum Cost to Make Array Equal.java @@ -0,0 +1,27 @@ +class Solution { + public long minCost(int[] nums, int[] cost) { + int n = nums.length; + int[][] numWithCost = new int[n][2]; + for (int i = 0; i < n; i++) { + numWithCost[i] = new int[]{nums[i], cost[i]}; + } + Arrays.sort(numWithCost, (a, b) -> a[0] - b[0]); + long[] prefixCost = new long[n]; + prefixCost[0] = numWithCost[0][1]; + for (int i = 1; i < n; i++) { + prefixCost[i] = numWithCost[i][1] + prefixCost[i - 1]; + } + long totalCost = 0; + for (int i = 1; i < n; i++) { + totalCost += 1L * numWithCost[i][1] * (numWithCost[i][0] - numWithCost[0][0]); + } + long result = totalCost; + for (int i = 1; i < n; ++i) { + int gap = numWithCost[i][0] - numWithCost[i - 1][0]; + totalCost += 1L * prefixCost[i - 1] * gap; + totalCost -= 1L * (prefixCost[n - 1] - prefixCost[i - 1]) * gap; + result = Math.min(result, totalCost); + } + return result; + } +} diff --git a/Hard/Minimum Difficulty of a Job Schedule.java b/Hard/Minimum Difficulty of a Job Schedule.java new file mode 100644 index 00000000..ebc94cc7 --- /dev/null +++ b/Hard/Minimum Difficulty of a Job Schedule.java @@ -0,0 +1,30 @@ +class Solution { + + private static final int INVALID_VALUE = 300_001; + + public int minDifficulty(int[] jobDifficulty, int d) { + if (jobDifficulty.length < d) { + return -1; + } + Integer[][][] dp = new Integer[jobDifficulty.length][d + 1][1001]; + return dfs(jobDifficulty, 0, d, 0, dp); + } + + private int dfs(int[] jobDifficulty, int idx, int d, int currMax, Integer[][][] dp) { + if (idx == jobDifficulty.length) { + return d == 0 ? 0 : INVALID_VALUE; + } + if (d == 0) { + return INVALID_VALUE; + } + if (dp[idx][d][currMax] != null) { + return dp[idx][d][currMax]; + } + currMax = Math.max(currMax, jobDifficulty[idx]); + int result = Math.min(dfs( + jobDifficulty, idx + 1, d, currMax, dp), // continue same sequence + currMax + dfs(jobDifficulty, idx + 1, d - 1, 0, dp) // break sequence + ); + return dp[idx][d][currMax] = result; + } +} diff --git a/Hard/Minimum Insertion Steps to Make a String Palindrome.java b/Hard/Minimum Insertion Steps to Make a String Palindrome.java new file mode 100644 index 00000000..3ffd2f07 --- /dev/null +++ b/Hard/Minimum Insertion Steps to Make a String Palindrome.java @@ -0,0 +1,22 @@ +class Solution { + public int minInsertions(String s) { + int n = s.length(); + return n - lcs(s, new StringBuilder(s).reverse().toString(), n, n); + } + + private int lcs(String s1, String s2, int m, int n) { + int[][] dp = new int[m + 1][n + 1]; + for (int i = 0; i <= m; i++) { + for (int j = 0; j <= n; j++) { + if (i == 0 || j == 0) { + dp[i][j] = 0; + } else if (s1.charAt(i - 1) == s2.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[m][n]; + } +} diff --git a/Hard/Minimum Number of Operations to Make Array Continuous.java b/Hard/Minimum Number of Operations to Make Array Continuous.java new file mode 100644 index 00000000..f6f07059 --- /dev/null +++ b/Hard/Minimum Number of Operations to Make Array Continuous.java @@ -0,0 +1,25 @@ +class Solution { + public int minOperations(int[] nums) { + Set set = new HashSet<>(); + for (int num : nums) { + set.add(num); + } + int[] arr = new int[set.size()]; + int idx = 0; + for (Integer num : set) { + arr[idx++] = num; + } + Arrays.sort(arr); + int n = nums.length; + int result = n; + int j = 0; + for (int i = 0; i < arr.length; i++) { + while (j < arr.length && arr[j] < arr[i] + n) { + j++; + } + int count = j - i; + result = Math.min(result, n - count); + } + return result; + } +} diff --git a/Hard/Minimum Number of Refueling Stops.java b/Hard/Minimum Number of Refueling Stops.java new file mode 100644 index 00000000..217cbe08 --- /dev/null +++ b/Hard/Minimum Number of Refueling Stops.java @@ -0,0 +1,27 @@ +class Solution { + public int minRefuelStops(int target, int startFuel, int[][] stations) { + PriorityQueue pq = new PriorityQueue<>(Collections.reverseOrder()); + int result = 0; + int prev = 0; + for (int[] station : stations) { + int location = station[0]; + int capacity = station[1]; + startFuel -= location - prev; + while (!pq.isEmpty() && startFuel < 0) { + startFuel += pq.poll(); + result++; + } + if (startFuel < 0) { + return -1; + } + pq.add(capacity); + prev = location; + } + startFuel -= target - prev; + while (!pq.isEmpty() && startFuel < 0) { + startFuel += pq.poll(); + result++; + } + return startFuel < 0 ? -1 : result; + } +} diff --git a/Hard/Minimum Number of Removals to Make Mountain Array.java b/Hard/Minimum Number of Removals to Make Mountain Array.java new file mode 100644 index 00000000..b74f6feb --- /dev/null +++ b/Hard/Minimum Number of Removals to Make Mountain Array.java @@ -0,0 +1,30 @@ +class Solution { + public int minimumMountainRemovals(int[] nums) { + int n = nums.length; + int[] leftIncreasingLength = new int[n]; + int[] rightDecreasingLength = new int[n]; + Arrays.fill(leftIncreasingLength, 1); + Arrays.fill(rightDecreasingLength, 1); + for (int i = 0; i < n; i++) { + for (int j = i - 1; j >= 0; j--) { + if (nums[i] > nums[j]) { + leftIncreasingLength[i] = Math.max(leftIncreasingLength[i], leftIncreasingLength[j] + 1); + } + } + } + for (int i = n - 1; i >= 0; i--) { + for (int j = i + 1; j < n; j++) { + if (nums[i] > nums[j]) { + rightDecreasingLength[i] = Math.max(rightDecreasingLength[i], rightDecreasingLength[j] + 1); + } + } + } + int minRemovals = Integer.MAX_VALUE; + for (int i = 0; i < n; i++) { + if (leftIncreasingLength[i] > 1 && rightDecreasingLength[i] > 1) { + minRemovals = Math.min(minRemovals, n - leftIncreasingLength[i] - rightDecreasingLength[i] + 1); + } + } + return minRemovals; + } +} diff --git a/Hard/Minimum Replacements to Sort the Array.java b/Hard/Minimum Replacements to Sort the Array.java new file mode 100644 index 00000000..1c3cfc4f --- /dev/null +++ b/Hard/Minimum Replacements to Sort the Array.java @@ -0,0 +1,14 @@ +class Solution { + public long minimumReplacement(int[] nums) { + int n = nums.length; + long numOfOperations = 0; + for (int i = n - 2; i >= 0; i--) { + if (nums[i] > nums[i + 1]) { + long numElements = (long)(nums[i] + nums[i + 1] - 1) / (long)nums[i + 1]; + numOfOperations += numElements - 1; + nums[i] = nums[i] / (int)numElements; + } + } + return numOfOperations; + } +} diff --git a/Hard/Minimum Window Subsequence.java b/Hard/Minimum Window Subsequence.java new file mode 100644 index 00000000..d1a9b971 --- /dev/null +++ b/Hard/Minimum Window Subsequence.java @@ -0,0 +1,39 @@ +class Solution { + public String minWindow(String s1, String s2) { + int right = 0; + int minWindowLength = Integer.MAX_VALUE; + String result = ""; + while (right < s1.length()) { + int s2Idx = 0; + while (right < s1.length()) { + if (s1.charAt(right) == s2.charAt(s2Idx)) { + s2Idx++; + } + if (s2Idx == s2.length()) { + break; + } + right++; + } + if (right == s1.length()) { + break; + } + int s1EndIdx = right; + int s2EndIdx = s2.length() - 1; + while (s1EndIdx >= 0) { + if (s1.charAt(s1EndIdx) == s2.charAt(s2EndIdx)) { + s2EndIdx--; + } + if (s2EndIdx < 0) { + break; + } + s1EndIdx--; + } + if (right - s1EndIdx + 1 < minWindowLength) { + minWindowLength = right - s1EndIdx + 1; + result = s1.substring(s1EndIdx, right + 1); + } + right = s1EndIdx + 1; + } + return result; + } +} diff --git a/Hard/Minimum Window Substring.java b/Hard/Minimum Window Substring.java index b5d6ae76..40cfa2ce 100644 --- a/Hard/Minimum Window Substring.java +++ b/Hard/Minimum Window Substring.java @@ -2,42 +2,37 @@ class Solution { public String minWindow(String s, String t) { Map map = new HashMap<>(); for (char c : t.toCharArray()) { - map.put(c, (map.getOrDefault(c, 0) + 1)); + map.put(c, map.getOrDefault(c, 0) + 1); } - + int targetSize = map.size(); int start = 0; - int end = 0; - int count = map.size(); - int minLen = Integer.MAX_VALUE; - String ans = ""; - - while (end < s.length()) { - if (map.containsKey(s.charAt(end))) { - map.put(s.charAt(end), map.get(s.charAt(end)) - 1); - if (map.get(s.charAt(end)) == 0) { - count--; + int minLength = Integer.MAX_VALUE; + int minStart = -1; + int minEnd = -1; + int n = s.length(); + for (int i = 0; i < n; i++) { + if (map.containsKey(s.charAt(i))) { + map.put(s.charAt(i), map.get(s.charAt(i)) - 1); + if (map.get(s.charAt(i)) == 0) { + targetSize--; } } - - end++; - - while (count == 0) { - if (end - start < minLen) { - minLen = end - start; - ans = s.substring(start, end); - } - + while (start <= i && targetSize == 0) { + int currLength = i - start; + if (minLength > currLength) { + minLength = currLength; + minStart = start; + minEnd = i + 1; + } if (map.containsKey(s.charAt(start))) { map.put(s.charAt(start), map.get(s.charAt(start)) + 1); - if (map.get(s.charAt(start)) > 0) { - count++; + if (map.get(s.charAt(start)) == 1) { + targetSize++; } } - start++; } } - - return ans; + return minLength == Integer.MAX_VALUE ? "" : s.substring(minStart, minEnd); } } diff --git a/Hard/My Calendar III.java b/Hard/My Calendar III.java new file mode 100644 index 00000000..47a51702 --- /dev/null +++ b/Hard/My Calendar III.java @@ -0,0 +1,26 @@ +class MyCalendarThree { + + private TreeMap delta; + + public MyCalendarThree() { + this.delta = new TreeMap<>(); + } + + public int book(int start, int end) { + delta.put(start, delta.getOrDefault(start, 0) + 1); + delta.put(end, delta.getOrDefault(end, 0) - 1); + int activeEvents = 0; + int maxEvents = 0; + for (int d : delta.values()) { + activeEvents += d; + maxEvents = Math.max(maxEvents, activeEvents); + } + return maxEvents; + } +} + +/** + * Your MyCalendarThree object will be instantiated and called as such: + * MyCalendarThree obj = new MyCalendarThree(); + * int param_1 = obj.book(start,end); + */ diff --git a/Hard/N-Queens II.java b/Hard/N-Queens II.java new file mode 100644 index 00000000..0cc14059 --- /dev/null +++ b/Hard/N-Queens II.java @@ -0,0 +1,29 @@ +class Solution { + public int totalNQueens(int n) { + return backtrack(0, new HashSet<>(), new HashSet<>(), new HashSet<>(), n); + } + + private int backtrack(int row, Set diagonals, Set antiDiagonals, Set columns, int n) { + if (row == n) { + return 1; + } + int possibleSolutions = 0; + for (int col = 0; col < n; col++) { + int currDiagonal = row - col; + int currAntiDiagonal = row + col; + if (columns.contains(col) || diagonals.contains(currDiagonal) || antiDiagonals.contains(currAntiDiagonal)) { + continue; + } + columns.add(col); + diagonals.add(currDiagonal); + antiDiagonals.add(currAntiDiagonal); + + possibleSolutions += backtrack(row + 1, diagonals, antiDiagonals, columns, n); + + columns.remove(col); + diagonals.remove(currDiagonal); + antiDiagonals.remove(currAntiDiagonal); + } + return possibleSolutions; + } +} diff --git a/Hard/N-Queens.java b/Hard/N-Queens.java index 2e382180..0551c884 100644 --- a/Hard/N-Queens.java +++ b/Hard/N-Queens.java @@ -1,50 +1,45 @@ class Solution { public List> solveNQueens(int n) { - List> ans = new ArrayList <>(); - helper(n, 0, new ArrayList<>(), ans); - return ans; + List> result = new ArrayList<>(); + char[][] board = new char[n][n]; + for (char[] row : board) { + Arrays.fill(row, '.'); + } + backtrack(0, new HashSet<>(), new HashSet<>(), new HashSet<>(), board, result, n); + return result; } - - private void helper(int n, int row, List selections, List> ans) { + + private void backtrack(int row, Set diagonals, Set antiDiagonals, Set columns, char[][] board, List> result, int n) { if (row == n) { - ans.add(convertToString(selections, n)); + result.add(buildBoard(board, n)); + return; } - else { - for (int i = 0; i < n; i++) { - selections.add(i); - if (isValid(selections)) { - helper(n, row + 1, selections, ans); - } - selections.remove(selections.size() - 1); + for (int col = 0; col < n; col++) { + int currDiagonal = row - col; + int currAntiDiagonal = row + col; + if (columns.contains(col) || diagonals.contains(currDiagonal) || antiDiagonals.contains(currAntiDiagonal)) { + continue; } - } - } + columns.add(col); + diagonals.add(currDiagonal); + antiDiagonals.add(currAntiDiagonal); + board[row][col] = 'Q'; - private List convertToString(List selections, int n) { - List ret = new ArrayList<>(); - for (int i = 0; i < selections.size(); i++) { - StringBuilder sb = new StringBuilder(); - for (int j = 0; j < n; j++) { - if (j == selections.get(i)) { - sb.append("Q"); - } - else { - sb.append("."); - } - } - ret.add(sb.toString()); + backtrack(row + 1, diagonals, antiDiagonals, columns, board, result, n); + + columns.remove(col); + diagonals.remove(currDiagonal); + antiDiagonals.remove(currAntiDiagonal); + board[row][col] = '.'; } - return ret; } - - private boolean isValid(List selections) { - int row = selections.size() - 1; - for (int i = 0; i < row; i++) { - int diff = Math.abs(selections.get(i) - selections.get(row)); - if (diff == 0 || diff == row - i) { - return false; - } + + private List buildBoard(char[][] board, int n) { + List resultBoard = new ArrayList<>(); + for (int row = 0; row < n; row++) { + String currentRow = new String(board[row]); + resultBoard.add(currentRow); } - return true; + return resultBoard; } } diff --git a/Hard/Naming a Company.java b/Hard/Naming a Company.java new file mode 100644 index 00000000..c24f78fe --- /dev/null +++ b/Hard/Naming a Company.java @@ -0,0 +1,26 @@ +class Solution { + public long distinctNames(String[] ideas) { + Map> map = new HashMap<>(); + for (String idea : ideas) { + map.computeIfAbsent(idea.charAt(0), k -> new HashSet<>()).add(idea.substring(1, idea.length())); + } + long result = 0; + for (Character key1 : map.keySet()) { + for (Character key2 : map.keySet()) { + if (key1 == key2) { + continue; + } + int intersection = 0; + for (String word : map.get(key1)) { + if (map.get(key2).contains(word)) { + intersection++; + } + } + int distinctOne = map.get(key1).size() - intersection; + int distinctTwo = map.get(key2).size() - intersection; + result += distinctOne * distinctTwo; + } + } + return result; + } +} diff --git a/Hard/Number of Flowers in Full Bloom.java b/Hard/Number of Flowers in Full Bloom.java new file mode 100644 index 00000000..37bb43e7 --- /dev/null +++ b/Hard/Number of Flowers in Full Bloom.java @@ -0,0 +1,25 @@ +class Solution { + public int[] fullBloomFlowers(int[][] flowers, int[] people) { + int[] peopleCopy = Arrays.copyOf(people, people.length); + Arrays.sort(peopleCopy); + Arrays.sort(flowers, (a, b) -> Arrays.compare(a, b)); + Map map = new HashMap<>(); + PriorityQueue pq = new PriorityQueue<>(); + int idx = 0; + for (int person : peopleCopy) { + while (idx < flowers.length && flowers[idx][0] <= person) { + pq.add(flowers[idx][1]); + idx++; + } + while (!pq.isEmpty() && pq.peek() < person) { + pq.poll(); + } + map.put(person, pq.size()); + } + int[] result = new int[people.length]; + for (int i = 0; i < people.length; i++) { + result[i] = map.get(people[i]); + } + return result; + } +} diff --git a/Hard/Number of Squareful Arrays.java b/Hard/Number of Squareful Arrays.java index 5903c367..b21f3889 100644 --- a/Hard/Number of Squareful Arrays.java +++ b/Hard/Number of Squareful Arrays.java @@ -1,39 +1,35 @@ class Solution { - public int numSquarefulPerms(int[] A) { - Map count = new HashMap<>(); - Map> graph = new HashMap<>(); - int n = A.length; - for (int num : A) { - count.put(num, count.getOrDefault(num, 0) + 1); + public int numSquarefulPerms(int[] nums) { + Arrays.sort(nums); + int[] count = {0}; + backtrack(new ArrayList<>(), nums, new boolean[nums.length], -1, count); + return count[0]; + } + + private void backtrack(List temp, int[] nums, boolean[] used, int lastNumber, int[] count) { + if (temp.size() == nums.length){ + count[0]++; + return; } - for (Integer key1 : count.keySet()) { - graph.computeIfAbsent(key1, k -> new ArrayList<>()); - for (Integer key2 : count.keySet()) { - int r = (int) (Math.sqrt(key1 + key2) + 0.5); - if (r * r == key1 + key2) { - graph.get(key1).add(key2); + for (int i = 0; i < nums.length; i++){ + if (used[i] || (i > 0 && nums[i] == nums[i - 1] && !used[i - 1])){ + continue; + } + if (lastNumber != -1) { + if (!isSquare(nums[i] + lastNumber)) { + continue; } } + used[i] = true; + temp.add(nums[i]); + backtrack(temp, nums, used, nums[i], count); + temp.remove(temp.size() - 1); + used[i] = false; } - int ans = 0; - for (Integer key : count.keySet()) { - ans += dfs(key, n - 1, count, graph); - } - return ans; } - private int dfs(int key, int toReach, Map count, Map> graph) { - count.put(key, count.get(key) - 1); - int currAns = 1; - if (toReach != 0) { - currAns = 0; - for (int node : graph.get(key)) { - if (count.get(node) != 0) { - currAns += dfs(node, toReach - 1, count, graph); - } - } - } - count.put(key, count.get(key) + 1); - return currAns; + private boolean isSquare(int num) { + int squareRoot = (int) Math.sqrt(num); + return squareRoot * squareRoot == num; } } diff --git a/Hard/Number of Submatrices That Sum to Target.java b/Hard/Number of Submatrices That Sum to Target.java index edd19f0d..d8f9dfc5 100644 --- a/Hard/Number of Submatrices That Sum to Target.java +++ b/Hard/Number of Submatrices That Sum to Target.java @@ -1,29 +1,26 @@ class Solution { - public int numSubmatrixSumTarget(int[][] matrix, int target) { - int rows = matrix.length; - int cols = matrix[0].length; - int res = 0; - - for (int i = 0; i < rows; i++) { - for (int j = 1; j < cols; j++) { - matrix[i][j] += matrix[i][j - 1]; - } - } - - for (int i = 0; i < cols; i++) { - for (int j = i; j < cols; j++) { - Map map = new HashMap<>(); - map.put(0, 1); - int sum = 0; - for (int k = 0; k < rows; k++) { - sum += matrix[k][j] - (i > 0 ? matrix[k][i - 1] : 0); - res += map.getOrDefault(sum - target, 0); - - map.put(sum, map.getOrDefault(sum, 0) + 1); - } - } + public int numSubmatrixSumTarget(int[][] matrix, int target) { + int rows = matrix.length; + int cols = matrix[0].length; + int[][] prefixSum = new int[rows + 1][cols + 1]; + for (int i = 1; i <= rows; i++) { + for (int j = 1; j <= cols; j++) { + prefixSum[i][j] = prefixSum[i - 1][j] + prefixSum[i][j - 1] - prefixSum[i - 1][j - 1] + matrix[i - 1][j - 1]; + } + } + int count = 0; + int currSum = 0; + for (int i = 1; i <= rows; i++) { + for (int j = i; j <= rows; j++) { + Map map = new HashMap<>(); + map.put(0, 1); + for (int k = 1; k <= cols; k++) { + currSum = prefixSum[j][k] - prefixSum[i - 1][k]; + count += map.getOrDefault(currSum - target, 0); + map.put(currSum, map.getOrDefault(currSum, 0) + 1); } - - return res; + } } + return count; + } } diff --git a/Hard/Number of Ways of Cutting a Pizza.java b/Hard/Number of Ways of Cutting a Pizza.java new file mode 100644 index 00000000..a96b2064 --- /dev/null +++ b/Hard/Number of Ways of Cutting a Pizza.java @@ -0,0 +1,37 @@ +class Solution { + + private static final int MOD = 1000_000_007; + + public int ways(String[] pizza, int k) { + int rows = pizza.length; + int cols = pizza[0].length(); + int[][] apples = new int[rows + 1][cols + 1]; + int[][][] dp = new int[k][rows][cols]; + for (int row = rows - 1; row >= 0; row--) { + for (int col = cols - 1; col >= 0; col--) { + apples[row][col] = (pizza[row].charAt(col) == 'A' ? 1 : 0) + apples[row + 1][col] + apples[row][col + 1] - apples[row + 1][col + 1]; + dp[0][row][col] = apples[row][col] > 0 ? 1 : 0; + } + } + + for (int i = 1; i < k; i++) { + for (int row = 0; row < rows; row++) { + for (int col = 0; col < cols; col++) { + for (int nextRow = row + 1; nextRow < rows; nextRow++) { + if (apples[row][col] - apples[nextRow][col] > 0) { + dp[i][row][col] += dp[i - 1][nextRow][col]; + dp[i][row][col] %= MOD; + } + } + for (int nextCol = col + 1; nextCol < cols; nextCol++) { + if (apples[row][col] - apples[row][nextCol] > 0) { + dp[i][row][col] += dp[i - 1][row][nextCol]; + dp[i][row][col] %= MOD; + } + } + } + } + } + return dp[k - 1][0][0]; + } +} diff --git a/Hard/Number of Ways to Form a Target String Given a Dictionary.java b/Hard/Number of Ways to Form a Target String Given a Dictionary.java new file mode 100644 index 00000000..a6354f1f --- /dev/null +++ b/Hard/Number of Ways to Form a Target String Given a Dictionary.java @@ -0,0 +1,28 @@ +class Solution { + + private static final int MOD = 1000_000_007; + + public int numWays(String[] words, String target) { + int m = target.length(); + int k = words[0].length(); + int[][] count = new int[26][k]; + for (int i = 0; i < k; i++) { + for (String word : words) { + count[word.charAt(i) - 'a'][i]++; + } + } + long[][] dp = new long[m + 1][k + 1]; + dp[0][0] = 1l; + for (int i = 0; i <= m; i++) { + for (int j = 0; j < k; j++) { + if (i < m) { + dp[i + 1][j + 1] += count[target.charAt(i) - 'a'][j] * dp[i][j]; + dp[i + 1][j + 1] %= MOD; + } + dp[i][j + 1] += dp[i][j]; + dp[i][j + 1] %= MOD; + } + } + return (int) dp[m][k]; + } +} diff --git a/Hard/Number of Ways to Reorder Array to Get Same BST.java b/Hard/Number of Ways to Reorder Array to Get Same BST.java new file mode 100644 index 00000000..a47c1f1d --- /dev/null +++ b/Hard/Number of Ways to Reorder Array to Get Same BST.java @@ -0,0 +1,38 @@ +class Solution { + + private static final long MOD = 1000_000_007; + + public int numOfWays(int[] nums) { + int n = nums.length; + long[][] dp = new long[n][n]; + for (int i = 0; i < n; i++) { + dp[i][0] = dp[i][i] = 1; + } + for (int i = 2; i < n; i++) { + for (int j = 1; j < i; j++) { + dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j]) % MOD; + } + } + List list = Arrays.stream(nums).boxed().collect(Collectors.toList()); + return (int) ((dfs(list, dp) - 1) % MOD); + } + + private long dfs(List nums, long[][] dp) { + int n = nums.size(); + if (n < 3) { + return 1; + } + List leftNodes = new ArrayList<>(); + List rightNodes = new ArrayList<>(); + for (int i = 1; i < n; i++) { + if (nums.get(i) < nums.get(0)) { + leftNodes.add(nums.get(i)); + } else { + rightNodes.add(nums.get(i)); + } + } + long leftCount = dfs(leftNodes, dp) % MOD; + long rightCount = dfs(rightNodes, dp) % MOD; + return (((leftCount * rightCount) % MOD) * dp[n - 1][leftNodes.size()]) % MOD; + } +} diff --git a/Hard/Number of Ways to Stay in the Same Place After Some Steps.java b/Hard/Number of Ways to Stay in the Same Place After Some Steps.java new file mode 100644 index 00000000..a9ce7edf --- /dev/null +++ b/Hard/Number of Ways to Stay in the Same Place After Some Steps.java @@ -0,0 +1,23 @@ +class Solution { + + private static final int MOD = 1000_000_007; + + public int numWays(int steps, int arrLen) { + arrLen = Math.min(arrLen, steps); + int[][] dp = new int[arrLen][steps + 1]; + dp[0][0] = 1; + for (int i = 1; i <= steps; i++) { + for (int j = arrLen - 1; j >= 0; j--) { + int result = dp[j][i - 1]; + if (j > 0) { + result = (result + dp[j - 1][i - 1]) % MOD; + } + if (j < arrLen - 1) { + result = (result + dp[j + 1][i - 1]) % MOD; + } + dp[j][i] = result; + } + } + return dp[0][steps]; + } +} diff --git a/Hard/Paint House II.java b/Hard/Paint House II.java new file mode 100644 index 00000000..23ac7a3d --- /dev/null +++ b/Hard/Paint House II.java @@ -0,0 +1,28 @@ +class Solution { + public int minCostII(int[][] costs) { + int n = costs.length; + int k = costs[0].length; + int[][] dp = new int[n][k]; + for (int i = 0; i < k; i++) { + dp[0][i] = costs[0][i]; + } + for (int i = 1; i < n; i++) { + for (int j = 0; j < k; j++) { + dp[i][j] = minCost(dp[i - 1], j) + costs[i][j]; + } + } + return minCost(dp[n - 1], -1); + } + + private int minCost(int[] dp, int currPaintIdx) { + int cost = Integer.MAX_VALUE; + int idx = 0; + while (idx < dp.length) { + if (!(currPaintIdx != -1 && idx == currPaintIdx)) { + cost = Math.min(cost, dp[idx]); + } + idx++; + } + return cost; + } +} diff --git a/Hard/Paint House III.java b/Hard/Paint House III.java new file mode 100644 index 00000000..461973f0 --- /dev/null +++ b/Hard/Paint House III.java @@ -0,0 +1,37 @@ +class Solution { + private static final int MAXIMUM_POSSIBLE_COST = 1000001; + + public int minCost(int[] houses, int[][] cost, int m, int n, int target) { + Integer[][][] dp = new Integer[m + 1][target + 1][n + 1]; // [Current House][Neighborhood Count][Previous Color] + int result = helper(houses, cost, target, 0, 0, dp); + return result == MAXIMUM_POSSIBLE_COST ? -1 : result; + } + + public int helper(int[] houses, int[][] cost, int target, int idx, int numOfNeighbourhood, Integer[][][] dp) { + if (idx == houses.length) { + return numOfNeighbourhood != target ? MAXIMUM_POSSIBLE_COST : 0; + } + if (numOfNeighbourhood > target) { + return MAXIMUM_POSSIBLE_COST; + } + int prevHouseColor = idx == 0 ? 0 : houses[idx - 1]; + if (dp[idx][numOfNeighbourhood][prevHouseColor] != null) { + return dp[idx][numOfNeighbourhood][prevHouseColor]; + } + int minimumCost = MAXIMUM_POSSIBLE_COST; + if (houses[idx] != 0) { + int currColor = houses[idx]; + int updatedNumOfNeighbourhood = currColor != prevHouseColor ? numOfNeighbourhood + 1 : numOfNeighbourhood; + minimumCost = helper(houses, cost, target, idx + 1, updatedNumOfNeighbourhood, dp); + } else { + for (int currentColor = 1; currentColor <= cost[idx].length; currentColor++) { + houses[idx] = currentColor; // Color the house with currentColor + int updatedNumOfNeighbourhood = currentColor != prevHouseColor ? numOfNeighbourhood + 1 : numOfNeighbourhood; + int currCost = cost[idx][currentColor - 1] + helper(houses, cost, target, idx + 1, updatedNumOfNeighbourhood, dp); + minimumCost = Math.min(minimumCost, currCost); + houses[idx] = 0; // Remove the currentColor for recursion + } + } + return dp[idx][numOfNeighbourhood][prevHouseColor] = minimumCost; + } +} diff --git a/Hard/Painting the Walls.java b/Hard/Painting the Walls.java new file mode 100644 index 00000000..ceeb36f2 --- /dev/null +++ b/Hard/Painting the Walls.java @@ -0,0 +1,26 @@ +class Solution { + + private static final int INVALID_VALUE = 1000_000_000; + + public int paintWalls(int[] cost, int[] time) { + int n = cost.length; + Integer[][] dp = new Integer[n][n + 1]; + return compute(0, n, cost, time, dp, n); + } + + private int compute(int idx, int remain, int[] cost, int[] time, Integer[][] dp, int n) { + if (remain <= 0) { + return 0; + } + if (idx == n) { + return INVALID_VALUE; + } + if (dp[idx][remain] != null) { + return dp[idx][remain]; + } + int paint = cost[idx] + compute(idx + 1, remain - 1 - time[idx], cost, time, dp, n); + int noPaint = compute(idx + 1, remain, cost, time, dp, n); + dp[idx][remain] = Math.min(paint, noPaint); + return dp[idx][remain]; + } +} diff --git a/Hard/Palindrome Pairs.java b/Hard/Palindrome Pairs.java index a9ad8490..004bc645 100644 --- a/Hard/Palindrome Pairs.java +++ b/Hard/Palindrome Pairs.java @@ -1,54 +1,68 @@ class Solution { - public List> palindromePairs(String[] words) { - List> lists = new ArrayList<>(); - Map map = new HashMap<>(); - for (int i=0; i> palindromePairs(String[] words) { + TrieNode root = new TrieNode(); + for (int i = 0; i < words.length; i++) { + String reversed = new StringBuilder(words[i]).reverse().toString(); + TrieNode curr = root; + for (int j = 0; j < reversed.length(); j++) { + if (isPalindrome(reversed, j)) { + curr.palindromePrefixRemainingIds.add(i); } - - if (map.containsKey("")) { - for (int i = 0; i < words.length; i++) { - if (i == map.get("")) { - continue; - } - - if (palindromeCheck(words[i])) { - lists.add(Arrays.asList(map.get(""), i)); - } - } + if (!curr.children.containsKey(reversed.charAt(j))) { + curr.children.put(reversed.charAt(j), new TrieNode()); } - - for (int i=0; i> result = new ArrayList<>(); + for (int i = 0; i < words.length; i++) { + String word = words[i]; + TrieNode curr = root; + for (int j = 0; j < word.length(); j++) { + if (curr.wordEndingId != -1 && isPalindrome(word, j)) { + result.add(Arrays.asList(i, curr.wordEndingId)); + } + char c = word.charAt(j); + curr = curr.children.get(c); + if (curr == null) { + break; } - - return lists; + } + if (curr == null) { + continue; + } + if (curr.wordEndingId != -1 && curr.wordEndingId != i) { + result.add(Arrays.asList(i, curr.wordEndingId)); + } + for (int idx : curr.palindromePrefixRemainingIds) { + result.add(Arrays.asList(i, idx)); + } } + return result; + } + + private static boolean isPalindrome(String s, int start) { + int end = s.length() - 1; + while (start < end) { + if (s.charAt(start) != s.charAt(end)) { + return false; + } + start++; + end--; + } + return true; + } + + private static class TrieNode { + private int wordEndingId; + private Map children; + private List palindromePrefixRemainingIds; - private boolean palindromeCheck(String word) { - int i = 0; - int j = word.length() - 1; - - while (i < j) { - if (word.charAt(i) != word.charAt(j)) { - return false; - } - - i++; - j--; - } - - return true; + public TrieNode() { + this.wordEndingId = -1; + this.children = new HashMap<>(); + this.palindromePrefixRemainingIds = new ArrayList<>(); } + } } diff --git a/Hard/Parallel Courses III.java b/Hard/Parallel Courses III.java new file mode 100644 index 00000000..f557c244 --- /dev/null +++ b/Hard/Parallel Courses III.java @@ -0,0 +1,35 @@ +class Solution { + public int minimumTime(int n, int[][] relations, int[] time) { + Map> map = new HashMap<>(); + int[] indegree = new int[n + 1]; + for (int[] relation : relations) { + int course = relation[0]; + int prereq = relation[1]; + indegree[course]++; + map.computeIfAbsent(prereq, k -> new ArrayList<>()).add(course); + } + Queue queue = new LinkedList<>(); + int[] maxTime = new int[n + 1]; + for (int i = 1; i <= n; i++) { + if (indegree[i] == 0) { + queue.add(i); + maxTime[i] = time[i - 1]; + } + } + while (!queue.isEmpty()) { + int removed = queue.remove(); + for (Integer dependent : map.getOrDefault(removed, new ArrayList<>())) { + maxTime[dependent] = Math.max(maxTime[dependent], maxTime[removed] + time[dependent - 1]); + indegree[dependent]--; + if (indegree[dependent] == 0) { + queue.add(dependent); + } + } + } + int result = 0; + for (int i = 1; i <= n; i++) { + result = Math.max(result, maxTime[i]); + } + return result; + } +} diff --git a/Hard/Parallel Courses.java b/Hard/Parallel Courses.java deleted file mode 100644 index f2470294..00000000 --- a/Hard/Parallel Courses.java +++ /dev/null @@ -1,46 +0,0 @@ -class Solution { - public int minimumSemesters(int N, int[][] relations) { - Map> map = new HashMap<>(); - // A prerequisite counter for each course - int[] prereqs = new int[N + 1]; - - for (int[] relation : relations) { - map.computeIfAbsent(relation[0], k-> new ArrayList<>()).add(relation[1]); - prereqs[relation[1]]++; - } - - Queue queue = new LinkedList<>(); - - // Add all the courses which have no prerequisite - // So that we can take those courses in first semester - for (int i = 1; i <= N; i++) { - if (prereqs[i] == 0) { - queue.add(i); - } - } - - int semester = 0; - while (!queue.isEmpty()) { - int size = queue.size(); - while (size-- > 0) { - int course = queue.poll(); - // Decrement N as we have taken a course that is removed from the queue - N--; - for (int pre : map.getOrDefault(course, new ArrayList<>())) { - /* - If a course which depends upon the removed course had only the removed course as prereq then we can - add it to the queue - */ - if (--prereqs[pre] == 0) { - queue.add(pre); - } - } - } - - // Semester over. New semester starts - semester++; - } - - return N == 0 ? semester : -1; - } -} diff --git a/Hard/Parsing A Boolean Expression.java b/Hard/Parsing A Boolean Expression.java index 2c419aa8..97a56130 100644 --- a/Hard/Parsing A Boolean Expression.java +++ b/Hard/Parsing A Boolean Expression.java @@ -1,72 +1,43 @@ class Solution { public boolean parseBoolExpr(String expression) { - char[] chars = expression.toCharArray(); - Stack operations = new Stack<>(); - Stack boolValues = new Stack<>(); - - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - if (c == '!' || c == '&' || c == '|') { - operations.push(c); - } - else if (c == '(') { - boolValues.push('#'); - } - else if (c == 't' || c == 'f') { - boolValues.push(chars[i]); - } - else if (c == ',') { - continue; - } - else { - List list = new ArrayList<>(); - while (!boolValues.isEmpty()) { - char temp = boolValues.pop(); - if (temp == '#') { - break; - } - - list.add(temp); + Stack stack = new Stack<>(); + for (char c : expression.toCharArray()) { + if (c == ')') { + List values = new ArrayList<>(); + while (stack.peek() != '(') { + values.add(stack.pop()); } - - boolValues.push(performOperation(list, operations.pop())); + stack.pop(); + char operation = stack.pop(); + char result = evaluate(operation, values); + stack.push(result); + } else if (c != ',') { + stack.push(c); } } - - return boolValues.peek() == 't' ? true : false; + return stack.peek() == 't'; } - private Character performOperation(List list, Character operation) { - if (operation == '|') { - return performOr(list); - } - else if (operation == '&') { - return performAnd(list); + private static char evaluate(char operation, List values) { + if (operation == '!') { + return values.get(0) == 't' ? 'f' : 't'; } - else { - return list.get(0) == 't' ? 'f' : 't'; - } - } - - private Character performAnd(List list) { - boolean val = getBooleanValue(list.get(0)); - for (int i = 1; i < list.size(); i++) { - val &= getBooleanValue(list.get(i)); + if (operation == '&') { + for (char value : values) { + if (value == 'f') { + return 'f'; + } + } + return 't'; } - - return val ? 't' : 'f'; - } - - private Character performOr(List list) { - boolean val = getBooleanValue(list.get(0)); - for (int i = 1; i < list.size(); i++) { - val |= getBooleanValue(list.get(i)); + if (operation == '|') { + for (char value : values) { + if (value == 't') { + return 't'; + } + } + return 'f'; } - - return val ? 't' : 'f'; - } - - private boolean getBooleanValue(Character character) { - return character == 't' ? true : false; + return 'f'; } } diff --git a/Hard/Patching Array.java b/Hard/Patching Array.java new file mode 100644 index 00000000..6bf2a8ed --- /dev/null +++ b/Hard/Patching Array.java @@ -0,0 +1,16 @@ +class Solution { + public int minPatches(int[] nums, int n) { + int patches = 0; + long miss = 1; + int idx = 0; + while (miss <= n) { + if (idx < nums.length && nums[idx] <= miss) { + miss += nums[idx++]; + } else { + miss += miss; + patches++; + } + } + return patches; + } +} diff --git a/Hard/Perfect Rectangle.java b/Hard/Perfect Rectangle.java new file mode 100644 index 00000000..fb79a5e3 --- /dev/null +++ b/Hard/Perfect Rectangle.java @@ -0,0 +1,41 @@ +class Solution { + public boolean isRectangleCover(int[][] rectangles) { + int x1 = Integer.MAX_VALUE; + int x2 = Integer.MIN_VALUE; + int y1 = Integer.MAX_VALUE; + int y2 = Integer.MIN_VALUE; + Set set = new HashSet(); + int totalArea = 0; + for (int[] rectangle : rectangles) { + x1 = Math.min(rectangle[0], x1); + y1 = Math.min(rectangle[1], y1); + x2 = Math.max(rectangle[2], x2); + y2 = Math.max(rectangle[3], y2); + totalArea += (rectangle[2] - rectangle[0]) * (rectangle[3] - rectangle[1]); + String s1 = rectangle[0] + " " + rectangle[1]; + String s2 = rectangle[0] + " " + rectangle[3]; + String s3 = rectangle[2] + " " + rectangle[3]; + String s4 = rectangle[2] + " " + rectangle[1]; + if (!set.add(s1)) { + set.remove(s1); + } + if (!set.add(s2)) { + set.remove(s2); + } + if (!set.add(s3)) { + set.remove(s3); + } + if (!set.add(s4)) { + set.remove(s4); + } + } + if (!set.contains(x1 + " " + y1) || + !set.contains(x1 + " " + y2) || + !set.contains(x2 + " " + y1) || + !set.contains(x2 + " " + y2) || + set.size() != 4) { + return false; + } + return totalArea == (x2 - x1) * (y2 - y1); + } +} diff --git a/Hard/Poor Pigs.java b/Hard/Poor Pigs.java new file mode 100644 index 00000000..275fb45a --- /dev/null +++ b/Hard/Poor Pigs.java @@ -0,0 +1,6 @@ +class Solution { + public int poorPigs(int buckets, int minutesToDie, int minutesToTest) { + int states = minutesToTest / minutesToDie + 1; + return (int) Math.ceil(Math.log(buckets) / Math.log(states)); + } +} diff --git a/Hard/Prefix and Suffix Search.java b/Hard/Prefix and Suffix Search.java index 4a791c66..e7778aff 100644 --- a/Hard/Prefix and Suffix Search.java +++ b/Hard/Prefix and Suffix Search.java @@ -1,61 +1,48 @@ class WordFilter { - Node root; - Map weightMap; + private TrieNode root; + public WordFilter(String[] words) { - root = new Node('-'); - weightMap = new HashMap<>(); + this.root = new TrieNode(); for (int i = 0; i < words.length; i++) { - root.words.add(words[i]); - addWord(words[i], 0, root); - weightMap.put(words[i], i); - } - } - - private void addWord(String word, int idx, Node curr) { - if (idx == word.length()) { - return; + indexWord(words[i], i); } - char c = word.charAt(idx); - if (!curr.children.containsKey(c)) { - curr.children.put(c, new Node(c)); - } - curr = curr.children.get(c); - curr.words.add(word); - addWord(word, idx + 1, curr); } public int f(String prefix, String suffix) { - Node curr = root; - if (prefix.length() != 0) { - for (char c : prefix.toCharArray()) { - if (!curr.children.containsKey(c)) { - return -1; - } - curr = curr.children.get(c); + TrieNode curr = root; + for (char c : (suffix + "{" + prefix).toCharArray()) { + if (curr.children[c - 'a'] == null) { + return -1; } + curr = curr.children[c - 'a']; } - int ans = -1; - for (String word : curr.words) { - if (suffix.length() == 0 || word.endsWith(suffix)) { - ans = Math.max(ans, weightMap.get(word)); + return curr.maxIdx; + } + + private void indexWord(String word, int idx) { + for (int i = word.length() - 1; i >= 0; i--) { + String suffixAndPrefix = word.substring(i, word.length()) + "{" + word; + TrieNode curr = root; + for (char c : suffixAndPrefix.toCharArray()) { + if (curr.children[c - 'a'] == null) { + curr.children[c - 'a'] = new TrieNode(); + } + curr = curr.children[c - 'a']; + curr.maxIdx = idx; } } - return ans; } -} - - -class Node { - char c; - Map children; - Set words; - public Node(char c) { - this.c = c; - children = new HashMap<>(); - words = new HashSet<>(); - } + + private class TrieNode { + TrieNode[] children; + int maxIdx; + public TrieNode() { + this.children = new TrieNode[27]; + this.maxIdx = 0; + } + } } /** diff --git a/Hard/Profitable Schemes.java b/Hard/Profitable Schemes.java new file mode 100644 index 00000000..7a1cabc4 --- /dev/null +++ b/Hard/Profitable Schemes.java @@ -0,0 +1,23 @@ +class Solution { + + private static final int MOD = 1000_000_007; + + public int profitableSchemes(int n, int minProfit, int[] group, int[] profit) { + Integer[][][] dp = new Integer[101][101][101]; + return helper(0, 0, 0, n, minProfit, group, profit, dp); + } + + private int helper(int pos, int count, int profit, int n, int minProfit, int[] group, int[] profits, Integer[][][] dp) { + if (pos == group.length) { + return profit >= minProfit ? 1 : 0; + } + if (dp[pos][count][profit] != null) { + return dp[pos][count][profit]; + } + int totalWays = helper(pos + 1, count, profit, n, minProfit, group, profits, dp); + if (count + group[pos] <= n) { + totalWays += helper(pos + 1, count + group[pos], Math.min(minProfit, profit + profits[pos]), n, minProfit, group, profits, dp); + } + return dp[pos][count][profit] = totalWays % MOD; + } +} diff --git a/Hard/README.md b/Hard/README.md index 3bf228e4..0e44bb8b 100644 --- a/Hard/README.md +++ b/Hard/README.md @@ -1,57 +1,127 @@ # Hard LeetCode-Java-Solutions S.no | Coding Problem --- | --- -1|[Merge K Sorted Lists](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Merge%20K%20Sorted%20Lists.java) -2|[Serialize and Deserialize a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Serialize%20and%20Deserialize%20a%20Binary%20Tree.java) -3|[Palindrome Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Palindrome%20Pairs.java) -4|[Binary Tree PostOrder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Binary%20Tree%20PostOrder%20Traversal.java) -5|[Largest Rectangle in Histogram](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Largest%20Rectangle%20in%20Histogram.java) -6|[Trapping Rain Water](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Trapping%20Rain%20Water.java) -7|[Parallel Courses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Parallel%20Courses.java) -8|[LFU Cache](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/LFU%20Cache.java) -9|[Unique Paths III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Unique%20Paths%20III.java) -10|[Integer to English Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Integer%20to%20English%20Words.java) -11|[Number of Valid Subarrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Number%20of%20Valid%20Subarrays.java) -12|[Candy](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Candy.java) -13|[Odd Even Jump](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Odd%20Even%20Jump.java) -14|[Longest Consecutive Sequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Longest%20Consecutive%20Sequence.java) -15|[Substring with Concatenation of All Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Substring%20with%20Concatenation%20of%20All%20Words.java) -16|[Median of Two Sorted Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Median%20of%20Two%20Sorted%20Arrays.java) -17|[Hard](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Hard.md) -18|[Longest Substring with At Most K Distinct Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Longest%20Substring%20with%20At%20Most%20K%20Distinct%20Characters.java) -19|[Closest Binary Search Tree Values II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Closest%20Binary%20Search%20Tree%20Values%20II.java) -20|[Edit Distance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Edit%20Distance.java) -21|[Longest Palindrome Product](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Longest%20Palindrome%20Product.java) -22|[K Empty Slots](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/K%20Empty%20Slots.java) -23|[Cut Off Trees for Golf Event](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Cut%20Off%20Trees%20for%20Golf%20Event.java) -24|[Word Break II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Word%20Break%20II.java) -25|[LRU Cache](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/LRU%20Cache.java) -26|[Parsing A Boolean Expression](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Parsing%20A%20Boolean%20Expression.java) -27|[Maximum Frequency Stack](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Maximum%20Frequency%20Stack.java) -28|[N-Queens](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/N-Queens.java) -29|[Sliding Window Maximum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Sliding%20Window%20Maximum.java) -30|[Optimal Account Balancing](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Optimal%20Account%20Balancing.java) -31|[Divide Array Into Increasing Sequences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Divide%20Array%20Into%20Increasing%20Sequences.java) -32|[Serialize and Deserialize N-ary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Serialize%20and%20Deserialize%20N-ary%20Tree.java) -33|[Word Search II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Word%20Search%20II.java) -34|[Insert Delete GetRandom O(1) - Duplicates Allowed](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Insert%20Delete%20GetRandom%20O(1)%20-%20Duplicates%20Allowed.java) -35|[Recover a Tree From Preorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Recover%20a%20Tree%20From%20Preorder%20Traversal.java) -36|[Text Justification](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Text%20Justification.java) -37|[Find Median From Data Stream](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Find%20Median%20From%20Data%20Stream.java) -38|[Number of Submatrices That Sum to Target](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Number%20of%20Submatrices%20That%20Sum%20to%20Target.java) -39|[First Missing Positive](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/First%20Missing%20Positive.java) -40|[Minimum Window Substring](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Minimum%20Window%20Substring.java) -41|[Stream of Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Stream%20of%20Characters.java) -42|[Prefix and Suffix Search](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Prefix%20and%20Suffix%20Search.java) -43|[Longest Substring with At Most Two Distinct Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Longest%20Substring%20with%20At%20Most%20Two%20Distinct%20Characters.java) -44|[Find Minimum in Rotated Sorted Array II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Find%20Minimum%20in%20Rotated%20Sorted%20Array%20II.java) -45|[Sliding Window Median](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Sliding%20Window%20Median.java) -46|[Basic Calculator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Basic%20Calculator.java) -47|[Binary Tree Maximum Path Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Binary%20Tree%20Maximum%20Path%20Sum.java) -48|[Interleaving String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Interleaving%20String.java) -49|[Valid Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Valid%20Number.java) -50|[Robot Room Cleaner](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Robot%20Room%20Cleaner.java) -51|[Employee Free Time](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Employee%20Free%20Time.java) -52|[Design Search Autocomplete System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Design%20Search%20Autocomplete%20System.java) -53|[Basic Calculator III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Basic%20Calculator%20III.java) -54|[Longest Increasing Path in a Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Longest%20Increasing%20Path%20in%20a%20Matrix.java) +1|[Concatenated Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Concatenated%20Words.java) +2|[Minimum Cost to Make Array Equal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Minimum%20Cost%20to%20Make%20Array%20Equal.java) +3|[Max Stack](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Max%20Stack.java) +4|[Course Schedule III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Course%20Schedule%20III.java) +5|[Binary Tree Cameras](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Binary%20Tree%20Cameras.java) +6|[Remove Invalid Parentheses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Remove%20Invalid%20Parentheses.java) +7|[First Missing Positive](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/First%20Missing%20Positive.java) +8|[Reconstruct Itinerary](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Reconstruct%20Itinerary.java) +9|[Frog Jump](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Frog%20Jump.java) +10|[Sort Items by Groups Respecting Dependencies](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Sort%20Items%20by%20Groups%20Respecting%20Dependencies.java) +11|[Shortest Path Visiting All Nodes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Shortest%20Path%20Visiting%20All%20Nodes.java) +12|[Critical Connections in a Network](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Critical%20Connections%20in%20a%20Network.java) +13|[Sliding Window Median](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Sliding%20Window%20Median.java) +14|[Edit Distance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Edit%20Distance.java) +15|[Checking Existence of Edge Length Limited Paths](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Checking%20Existence%20of%20Edge%20Length%20Limited%20Paths.java) +16|[Perfect Rectangle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Perfect%20Rectangle.java) +17|[Minimum Window Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Minimum%20Window%20Subsequence.java) +18|[Remove Max Number of Edges to Keep Graph Fully Traversable](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Remove%20Max%20Number%20of%20Edges%20to%20Keep%20Graph%20Fully%20Traversable.java) +19|[K Inverse Pairs Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/K%20Inverse%20Pairs%20Array.java) +20|[Merge K Sorted Lists](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Merge%20K%20Sorted%20Lists.java) +21|[Minimum Replacements to Sort the Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Minimum%20Replacements%20to%20Sort%20the%20Array.java) +22|[Design Movie Rental System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Design%20Movie%20Rental%20System.java) +23|[Sliding Window Maximum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Sliding%20Window%20Maximum.java) +24|[My Calendar III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/My%20Calendar%20III.java) +25|[Longest Cycle in a Graph](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Longest%20Cycle%20in%20a%20Graph.java) +26|[Text Justification](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Text%20Justification.java) +27|[Design In-Memory File System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Design%20In-Memory%20File%20System.java) +28|[Basic Calculator III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Basic%20Calculator%20III.java) +29|[Integer to English Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Integer%20to%20English%20Words.java) +30|[Naming a Company](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Naming%20a%20Company.java) +31|[Minimum Number of Refueling Stops](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Minimum%20Number%20of%20Refueling%20Stops.java) +32|[Rearrange String k Distance Apart](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Rearrange%20String%20k%20Distance%20Apart.java) +33|[Make Array Strictly Increasing](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Make%20Array%20Strictly%20Increasing.java) +34|[Median of Two Sorted Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Median%20of%20Two%20Sorted%20Arrays.java) +35|[Vertical Order Traversal Of a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Vertical%20Order%20Traversal%20Of%20a%20Binary%20Tree.java) +36|[Divide Array Into Increasing Sequences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Divide%20Array%20Into%20Increasing%20Sequences.java) +37|[Word Break II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Word%20Break%20II.java) +38|[Maximum Number of Non-Overlapping Substrings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Maximum%20Number%20of%20Non-Overlapping%20Substrings.java) +39|[Paint House II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Paint%20House%20II.java) +40|[Subarrays with K Different Integers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Subarrays%20with%20K%20Different%20Integers.java) +41|[Maximum Performance of a Team](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Maximum%20Performance%20of%20a%20Team.java) +42|[Jump Game IV](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Jump%20Game%20IV.java) +43|[Paint House III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Paint%20House%20III.java) +44|[LFU Cache](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/LFU%20Cache.java) +45|[Scramble String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Scramble%20String.java) +46|[Word Search II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Word%20Search%20II.java) +47|[K Empty Slots](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/K%20Empty%20Slots.java) +48|[Employee Free Time](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Employee%20Free%20Time.java) +49|[Maximize Score After N Operations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Maximize%20Score%20After%20N%20Operations.java) +50|[Max Points on a Line](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Max%20Points%20on%20a%20Line.java) +51|[The Skyline Problem](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/The%20Skyline%20Problem.java) +52|[N-Queens](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/N-Queens.java) +53|[Longest Palindrome Product](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Longest%20Palindrome%20Product.java) +54|[Odd Even Jump](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Odd%20Even%20Jump.java) +55|[Palindrome Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Palindrome%20Pairs.java) +56|[Stream of Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Stream%20of%20Characters.java) +57|[Cut Off Trees for Golf Event](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Cut%20Off%20Trees%20for%20Golf%20Event.java) +58|[Kth Smallest Number in Multiplication Table](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Kth%20Smallest%20Number%20in%20Multiplication%20Table.java) +59|[String Compression II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/String%20Compression%20II.java) +60|[Minimize Deviation in Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Minimize%20Deviation%20in%20Array.java) +61|[Minimum Cost to Hire K Workers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Minimum%20Cost%20to%20Hire%20K%20Workers.java) +62|[Find the Longest Valid Obstacle Course at Each Position](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Find%20the%20Longest%20Valid%20Obstacle%20Course%20at%20Each%20Position.java) +63|[Number of Valid Subarrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Number%20of%20Valid%20Subarrays.java) +64|[Maximum Value of K Coins From Piles](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Maximum%20Value%20of%20K%20Coins%20From%20Piles.java) +65|[Substring with Concatenation of All Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Substring%20with%20Concatenation%20of%20All%20Words.java) +66|[Number of Paths with Max Score](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Number%20of%20Paths%20with%20Max%20Score.java) +67|[Profitable Schemes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Profitable%20Schemes.java) +68|[Design Search Autocomplete System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Design%20Search%20Autocomplete%20System.java) +69|[Number of Squareful Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Number%20of%20Squareful%20Arrays.java) +70|[N-Queens II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/N-Queens%20II.java) +71|[Robot Room Cleaner](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Robot%20Room%20Cleaner.java) +72|[Poor Pigs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Poor%20Pigs.java) +73|[Minimum Window Substring](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Minimum%20Window%20Substring.java) +74|[Number of Ways of Cutting a Pizza](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Number%20of%20Ways%20of%20Cutting%20a%20Pizza.java) +75|[Hard](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Hard.md) +76|[Parsing A Boolean Expression](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Parsing%20A%20Boolean%20Expression.java) +77|[Trapping Rain Water](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Trapping%20Rain%20Water.java) +78|[Similar String Groups](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Similar%20String%20Groups.java) +79|[Number of Ways to Form a Target String Given a Dictionary](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Number%20of%20Ways%20to%20Form%20a%20Target%20String%20Given%20a%20Dictionary.java) +80|[Find the Kth Smallest Sum of a Matrix With Sorted Rows](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Find%20the%20Kth%20Smallest%20Sum%20of%20a%20Matrix%20With%20Sorted%20Rows.java) +81|[Optimal Account Balancing](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Optimal%20Account%20Balancing.java) +82|[Design Skiplist](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Design%20Skiplist.java) +83|[Wildcard Matching](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Wildcard%20Matching.java) +84|[Expression Add Operators](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Expression%20Add%20Operators.java) +85|[Count of Smaller Numbers After Self](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Count%20of%20Smaller%20Numbers%20After%20Self.java) +86|[Number of Ways to Reorder Array to Get Same BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Number%20of%20Ways%20to%20Reorder%20Array%20to%20Get%20Same%20BST.java) +87|[Find Median from Data Stream](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Find%20Median%20from%20Data%20Stream.java) +88|[Best Time to Buy and Sell Stock IV](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Best%20Time%20to%20Buy%20and%20Sell%20Stock%20IV.java) +89|[Find Minimum in Rotated Sorted Array II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Find%20Minimum%20in%20Rotated%20Sorted%20Array%20II.java) +90|[Longest Valid Parentheses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Longest%20Valid%20Parentheses.java) +91|[Stone Game III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Stone%20Game%20III.java) +92|[Reducing Dishes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Reducing%20Dishes.java) +93|[Count Subarrays With Fixed Bounds](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Count%20Subarrays%20With%20Fixed%20Bounds.java) +94|[Stamping The Sequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Stamping%20The%20Sequence.java) +95|[Number of Submatrices That Sum to Target](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Number%20of%20Submatrices%20That%20Sum%20to%20Target.java) +96|[Candy](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Candy.java) +97|[Minimum Insertion Steps to Make a String Palindrome](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Minimum%20Insertion%20Steps%20to%20Make%20a%20String%20Palindrome.java) +98|[Shortest Distance from All Buildings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Shortest%20Distance%20from%20All%20Buildings.java) +99|[Recover a Tree From Preorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Recover%20a%20Tree%20From%20Preorder%20Traversal.java) +100|[Count Vowels Permutation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Count%20Vowels%20Permutation.java) +101|[Longest Increasing Path in a Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Longest%20Increasing%20Path%20in%20a%20Matrix.java) +102|[Maximum Profit in Job Scheduling](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Maximum%20Profit%20in%20Job%20Scheduling.java) +103|[Closest Binary Search Tree Values II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Closest%20Binary%20Search%20Tree%20Values%20II.java) +104|[Basic Calculator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Basic%20Calculator.java) +105|[Alien Dictionary](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Alien%20Dictionary.java) +106|[Prefix and Suffix Search](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Prefix%20and%20Suffix%20Search.java) +107|[Construct Target Array With Multiple Sums](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Construct%20Target%20Array%20With%20Multiple%20Sums.java) +108|[Tallest Billboard](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Tallest%20Billboard.java) +109|[Largest Color Value in a Directed Graph](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Largest%20Color%20Value%20in%20a%20Directed%20Graph.java) +110|[Valid Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Valid%20Number.java) +111|[Dice Roll Simulation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Dice%20Roll%20Simulation.java) +112|[Maximum Frequency Stack](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Maximum%20Frequency%20Stack.java) +113|[Reverse Nodes in k-Group](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Reverse%20Nodes%20in%20k-Group.java) +114|[Serialize and Deserialize N-ary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Serialize%20and%20Deserialize%20N-ary%20Tree.java) +115|[Serialize and Deserialize a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Serialize%20and%20Deserialize%20a%20Binary%20Tree.java) +116|[Minimum Difficulty of a Job Schedule](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Minimum%20Difficulty%20of%20a%20Job%20Schedule.java) +117|[Unique Paths III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Unique%20Paths%20III.java) +118|[Restore The Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Restore%20The%20Array.java) +119|[IPO](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/IPO.java) +120|[Insert Delete GetRandom O(1) - Duplicates Allowed](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Insert%20Delete%20GetRandom%20O(1)%20-%20Duplicates%20Allowed.java) +121|[Add Edges to Make Degrees of All Nodes Even](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Add%20Edges%20to%20Make%20Degrees%20of%20All%20Nodes%20Even.java) +122|[Maximum Sum BST in Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Maximum%20Sum%20BST%20in%20Binary%20Tree.java) +123|[Binary Tree Maximum Path Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Binary%20Tree%20Maximum%20Path%20Sum.java) +124|[Largest Rectangle in Histogram](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Hard/Largest%20Rectangle%20in%20Histogram.java) diff --git a/Hard/Rearrange String k Distance Apart.java b/Hard/Rearrange String k Distance Apart.java new file mode 100644 index 00000000..da212877 --- /dev/null +++ b/Hard/Rearrange String k Distance Apart.java @@ -0,0 +1,26 @@ +class Solution { + public String rearrangeString(String s, int k) { + Map map = new HashMap<>(); + for (char c : s.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); + } + PriorityQueue pq = new PriorityQueue<>((a, b) -> map.get(b).compareTo(map.get(a))); + Queue busy = new LinkedList<>(); + StringBuilder sb = new StringBuilder(); + pq.addAll(map.keySet()); + while (!pq.isEmpty()) { + Character removed = pq.poll(); + sb.append(removed); + map.put(removed, map.get(removed) - 1); + busy.add(removed); + if (busy.size() < k) { + continue; + } + Character busyRemoved = busy.remove(); + if (map.get(busyRemoved) > 0) { + pq.add(busyRemoved); + } + } + return sb.length() == s.length() ? sb.toString() : ""; + } +} diff --git a/Hard/Reconstruct Itinerary.java b/Hard/Reconstruct Itinerary.java new file mode 100644 index 00000000..e5616f94 --- /dev/null +++ b/Hard/Reconstruct Itinerary.java @@ -0,0 +1,19 @@ +class Solution { + public List findItinerary(List> tickets) { + Map> map = new HashMap<>(); + for (List ticket : tickets) { + map.computeIfAbsent(ticket.get(0), k -> new PriorityQueue<>()).add(ticket.get(1)); + } + Stack stack = new Stack<>(); + stack.push("JFK"); + List result = new ArrayList<>(); + while (!stack.isEmpty()) { + while (map.containsKey(stack.peek()) && !map.get(stack.peek()).isEmpty()) { + stack.push(map.get(stack.peek()).poll()); + } + result.add(stack.pop()); + } + Collections.reverse(result); + return result; + } +} diff --git a/Hard/Recover a Tree From Preorder Traversal.java b/Hard/Recover a Tree From Preorder Traversal.java index 69f3fe55..b851ca44 100644 --- a/Hard/Recover a Tree From Preorder Traversal.java +++ b/Hard/Recover a Tree From Preorder Traversal.java @@ -4,41 +4,45 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public TreeNode recoverFromPreorder(String S) { - Map map = new HashMap<>(); + public TreeNode recoverFromPreorder(String traversal) { + Stack stack = new Stack<>(); int idx = 0; - int n = S.length(); - - while (idx < n) { - int level = 0; - StringBuilder sb = new StringBuilder(); - - while (idx < n && S.charAt(idx) == '-') { - level++; + while (idx < traversal.length()) { + int depth = 0; + while (idx < traversal.length() && traversal.charAt(idx) == '-') { + depth++; idx++; } - - while (idx < n && Character.isDigit(S.charAt(idx))) { - sb.append(S.charAt(idx++)); + int value = 0; + while (idx < traversal.length() && Character.isDigit(traversal.charAt(idx))) { + value = value * 10 + Character.getNumericValue(traversal.charAt(idx++)); } - - TreeNode currNode = new TreeNode(Integer.parseInt(sb.toString())); - map.put(level, currNode); - if (level > 0) { - TreeNode parent = map.get(level - 1); - if (parent.left == null) { - parent.left = currNode; - } - else { - parent.right = currNode; + TreeNode node = new TreeNode(value); + while (stack.size() > depth) { + stack.pop(); + } + if (!stack.isEmpty()) { + if (stack.peek().left == null) { + stack.peek().left = node; + } else { + stack.peek().right = node; } } + stack.push(node); + } + while (stack.size() > 1) { + stack.pop(); } - - return map.get(0); + return stack.peek(); } } diff --git a/Hard/Reducing Dishes.java b/Hard/Reducing Dishes.java new file mode 100644 index 00000000..2a69540e --- /dev/null +++ b/Hard/Reducing Dishes.java @@ -0,0 +1,20 @@ +class Solution { + public int maxSatisfaction(int[] satisfaction) { + Arrays.sort(satisfaction); + int n = satisfaction.length; + Integer[][] dp = new Integer[n + 1][n + 1]; + return helper(satisfaction, 0, 1, dp); + } + + private int helper(int[] satisfaction, int idx, int time, Integer[][] dp) { + if (idx == satisfaction.length) { + return 0; + } + if (dp[idx][time] != null) { + return dp[idx][time]; + } + dp[idx][time] = Math.max(satisfaction[idx] * time + helper(satisfaction, idx + 1, time + 1, dp), + helper(satisfaction, idx + 1, time, dp)); + return dp[idx][time]; + } +} diff --git a/Hard/Remove Max Number of Edges to Keep Graph Fully Traversable.java b/Hard/Remove Max Number of Edges to Keep Graph Fully Traversable.java new file mode 100644 index 00000000..152ab81b --- /dev/null +++ b/Hard/Remove Max Number of Edges to Keep Graph Fully Traversable.java @@ -0,0 +1,67 @@ +class Solution { + public int maxNumEdgesToRemove(int n, int[][] edges) { + UnionFind alice = new UnionFind(n); + UnionFind bob = new UnionFind(n); + int requiredEdges = 0; + for (int[] edge : edges) { + if (edge[0] == 3) { + requiredEdges += (alice.union(edge[1], edge[2]) | bob.union(edge[1], edge[2])); + } + } + for (int[] edge : edges) { + if (edge[0] == 1) { + requiredEdges += alice.union(edge[1], edge[2]); + } else if (edge[0] == 2) { + requiredEdges += bob.union(edge[1], edge[2]); + } + } + if (alice.isConnected() && bob.isConnected()) { + return edges.length - requiredEdges; + } + return -1; + } + + private class UnionFind { + private final int[] representatives; + private final int[] componentSize; + private int components; + + public UnionFind(int n) { + this.representatives = new int[n + 1]; + this.componentSize = new int[n + 1]; + this.components = n; + for (int i = 0; i <= n; i++) { + componentSize[i] = 1; + representatives[i] = i; + } + } + + public int find(int x) { + if (representatives[x] == x) { + return x; + } + return representatives[x] = find(representatives[x]); + } + + public int union(int x, int y) { + x = find(x); + y = find(y); + if (x == y) { + return 0; + } + if (componentSize[x] > componentSize[y]) { + componentSize[x] += componentSize[y]; + representatives[y] = x; + } else { + componentSize[y] += componentSize[x]; + representatives[x] = y; + } + components--; + return 1; + } + + public boolean isConnected() { + return components == 1; + } + } +} diff --git a/Hard/Restore The Array.java b/Hard/Restore The Array.java new file mode 100644 index 00000000..9b6ffc76 --- /dev/null +++ b/Hard/Restore The Array.java @@ -0,0 +1,31 @@ +class Solution { + + private static final int MOD = 1000_000_007; + + public int numberOfArrays(String s, int k) { + int n = s.length(); + int[] dp = new int[n + 1]; + return dfs(dp, 0, s, k); + } + + private int dfs(int[] dp, int start, String s, int k) { + if (dp[start] != 0) { + return dp[start]; + } + if (start == s.length()) { + return 1; + } + if (s.charAt(start) == '0') { + return 0; + } + int count = 0; + for (int end = start; end < s.length(); end++) { + String currNum = s.substring(start, end + 1); + if (Long.parseLong(currNum) > k) { + break; + } + count = (count + dfs(dp, end + 1, s, k)) % MOD; + } + return dp[start] = count; + } +} diff --git a/Hard/Reverse Nodes in k-Group.java b/Hard/Reverse Nodes in k-Group.java index 66ab4ec1..f28071ac 100644 --- a/Hard/Reverse Nodes in k-Group.java +++ b/Hard/Reverse Nodes in k-Group.java @@ -10,47 +10,40 @@ */ class Solution { public ListNode reverseKGroup(ListNode head, int k) { - if (head == null) { - return null; - } - ListNode start = head; - ListNode curr = head; + ListNode newHead = null; ListNode prev = null; - ListNode revHead = null; + ListNode curr = head; while (curr != null) { - int count = 1; - while (curr.next != null && count < k) { + ListNode start = curr; + int idx = 1; + for (idx = 1; idx < k && curr.next != null; idx++) { curr = curr.next; - count++; } - if (count == k) { - ListNode next = curr.next; - curr.next = null; - if (revHead == null) { - revHead = curr; - } - ListNode reverse = reverse(start); - if (prev != null) { - prev.next = reverse; - } - start.next = next; - prev = start; - start = next; - curr = next; + if (idx != k) { + curr = null; + continue; } - else { - curr = curr.next; + ListNode next = curr.next; + curr.next = null; + ListNode reversedNode = reverse(start); + if (newHead == null) { + newHead = reversedNode; } + if (prev != null) { + prev.next = reversedNode; + } + prev = start; + start.next = next; + curr = next; } - return revHead == null ? head : revHead; - } + return newHead; + } - private ListNode reverse(ListNode root) { - ListNode curr = root; - ListNode next = null; + private ListNode reverse(ListNode node) { + ListNode curr = node; ListNode prev = null; while (curr != null) { - next = curr.next; + ListNode next = curr.next; curr.next = prev; prev = curr; curr = next; diff --git a/Hard/Robot Collisions.java b/Hard/Robot Collisions.java new file mode 100644 index 00000000..4202122c --- /dev/null +++ b/Hard/Robot Collisions.java @@ -0,0 +1,38 @@ +class Solution { + public List survivedRobotsHealths(int[] positions, int[] healths, String directions) { + int n = positions.length; + Integer[] indices = new Integer[n]; + for (int i = 0; i < n; i++) { + indices[i] = i; + } + Arrays.sort(indices, (a, b) -> Integer.compare(positions[a], positions[b])); + Stack stack = new Stack<>(); + for (Integer index : indices) { + if (directions.charAt(index) == 'R') { + stack.push(index); + } else { + while (!stack.isEmpty() && healths[index] > 0) { + int poppedIndex = stack.pop(); + if (healths[poppedIndex] > healths[index]) { + healths[poppedIndex]--; + healths[index] = 0; + stack.push(poppedIndex); + } else if (healths[poppedIndex] < healths[index]) { + healths[index]--; + healths[poppedIndex] = 0; + } else { + healths[poppedIndex] = 0; + healths[index] = 0; + } + } + } + } + List result = new ArrayList<>(); + for (int i = 0; i < n; i++) { + if (healths[i] > 0) { + result.add(healths[i]); + } + } + return result; + } +} diff --git a/Hard/Scramble String.java b/Hard/Scramble String.java new file mode 100644 index 00000000..ac35d39c --- /dev/null +++ b/Hard/Scramble String.java @@ -0,0 +1,25 @@ +class Solution { + public boolean isScramble(String s1, String s2) { + int n = s1.length(); + Boolean[][][] dp = new Boolean[n][n][n + 1]; + return helper(s1, s2, 0, 0, n, dp); + } + + private boolean helper(String s1, String s2, int idxOne, int idxTwo, int n, Boolean[][][] dp) { + if (dp[idxOne][idxTwo][n] != null) { + return dp[idxOne][idxTwo][n]; + } + if (n == 1) { + return dp[idxOne][idxTwo][n] = s1.charAt(idxOne) == s2.charAt(idxTwo); + } + for (int l = 1; l < n; l++) { + if (helper(s1, s2, idxOne, idxTwo, l, dp) && helper(s1, s2, idxOne + l, idxTwo + l, n - l, dp)) { + return dp[idxOne][idxTwo][n] = true; + } + if (helper(s1, s2, idxOne, idxTwo + n - l, l, dp) && helper(s1, s2, idxOne + l, idxTwo, n - l, dp)) { + return dp[idxOne][idxTwo][n] = true; + } + } + return dp[idxOne][idxTwo][n] = false; + } +} diff --git a/Hard/Serialize and Deserialize N-ary Tree.java b/Hard/Serialize and Deserialize N-ary Tree.java index 29d46233..d9df1fa3 100644 --- a/Hard/Serialize and Deserialize N-ary Tree.java +++ b/Hard/Serialize and Deserialize N-ary Tree.java @@ -16,48 +16,62 @@ public Node(int _val, List _children) { } }; */ + class Codec { - // Encodes a tree to a single string. - private final String SEPARATOR = ","; - private final String NULL_SEPARATOR = "#"; - public String serialize(Node root) { - StringBuilder sb = new StringBuilder(); - serializeHelper(root, sb); - return sb.toString(); - } - private void serializeHelper(Node root, StringBuilder sb) { + private static final String SEPARATOR = ","; + private static final String NULL_NODE = "X"; + + public String serialize(Node root) { if (root == null) { - sb.append(NULL_SEPARATOR).append(SEPARATOR); + return NULL_NODE; } - else { - sb.append(root.val).append(SEPARATOR).append(root.children.size()).append(SEPARATOR); - for (Node child : root.children) { - serializeHelper(child, sb); + StringBuilder sb = new StringBuilder(); + Queue queue = new LinkedList<>(); + queue.add(root); + queue.add(null); + while (!queue.isEmpty()) { + int size = queue.size(); + for (int i = 0; i < size; i++) { + Node removed = queue.remove(); + if (removed == null) { + sb.append(NULL_NODE).append(SEPARATOR); + break; + } + for (Node child : removed.children) { + queue.add(child); + } + queue.add(null); + sb.append(removed.val).append(SEPARATOR); } } + sb.deleteCharAt(sb.length() - 1); + return sb.toString(); } // Decodes your encoded data to tree. public Node deserialize(String data) { - Deque dq = new ArrayDeque<>(Arrays.asList(data.split(SEPARATOR))); - return deserializeHelper(dq); - } - - private Node deserializeHelper(Deque dq) { - String removed = dq.removeFirst(); - if (removed.equals(NULL_SEPARATOR)) { + String[] splits = data.split(SEPARATOR); + if (splits[0].equals(NULL_NODE)) { return null; } - else { - Node node = new Node(Integer.parseInt(removed), new ArrayList<>()); - int childCount = Integer.parseInt(dq.removeFirst()); - for (int i = 0; i < childCount; i++) { - node.children.add(deserializeHelper(dq)); + Node root = new Node(Integer.parseInt(splits[0])); + Queue queue = new LinkedList<>(); + queue.add(root); + int idx = 2; + while (idx < splits.length) { + Node node = queue.remove(); + List children = new ArrayList<>(); + while (!splits[idx].equals(NULL_NODE)) { + Node child = new Node(Integer.parseInt(splits[idx++])); + children.add(child); + queue.add(child); } - return node; + idx++; + node.children = children; } + return root; } } diff --git a/Hard/Serialize and Deserialize a Binary Tree.java b/Hard/Serialize and Deserialize a Binary Tree.java index d8b992b7..7639f07a 100644 --- a/Hard/Serialize and Deserialize a Binary Tree.java +++ b/Hard/Serialize and Deserialize a Binary Tree.java @@ -9,48 +9,50 @@ */ public class Codec { - // Encodes a tree to a single string. - public String serialize(TreeNode root) { - StringBuilder sb = new StringBuilder(); - serializeHelper(root, sb); - return sb.toString().substring(0, sb.length() - 1); + private static final String NULL_VALUE = "-"; + private static final String DELIMETER = " "; + + // Encodes a tree to a single string. + public String serialize(TreeNode root) { + if (root == null) { + return NULL_VALUE; } - - private void serializeHelper(TreeNode root, StringBuilder sb) { - if (root == null) { - sb.append("#").append(","); - return; - } - - sb.append(root.val).append(","); - serializeHelper(root.left, sb); - serializeHelper(root.right, sb); + StringBuilder sb = new StringBuilder(); + Stack stack = new Stack<>(); + stack.add(root); + while (!stack.isEmpty()) { + TreeNode removed = stack.pop(); + if (removed == null) { + sb.append(NULL_VALUE).append(DELIMETER); + continue; + } + sb.append(removed.val).append(DELIMETER); + stack.push(removed.right); + stack.push(removed.left); } + return sb.toString().trim(); + } - // Decodes your encoded data to tree. - public TreeNode deserialize(String data) { - Queue values = new LinkedList<>(Arrays.asList(data.split(","))); - return deserializeHelper(values); - } - - private TreeNode deserializeHelper(Queue values) { - if (values.isEmpty()) { - return null; - } - - String val = values.remove(); - if (val.equals("#")) { - return null; - } - - TreeNode root = new TreeNode(Integer.parseInt(val)); - root.left = deserializeHelper(values); - root.right = deserializeHelper(values); - - return root; + // Decodes your encoded data to tree. + public TreeNode deserialize(String data) { + Queue queue = new LinkedList<>(Arrays.asList(data.split("\\s+"))); + return helper(queue); + } + + private TreeNode helper(Queue queue) { + if (queue.peek().equals(NULL_VALUE)) { + queue.remove(); + return null; } + TreeNode root = new TreeNode(Integer.parseInt(queue.peek())); + queue.remove(); + root.left = helper(queue); + root.right = helper(queue); + return root; + } } // Your Codec object will be instantiated and called as such: -// Codec codec = new Codec(); -// codec.deserialize(codec.serialize(root)); +// Codec ser = new Codec(); +// Codec deser = new Codec(); +// TreeNode ans = deser.deserialize(ser.serialize(root)); diff --git a/Hard/Shortest Palindrome.java b/Hard/Shortest Palindrome.java new file mode 100644 index 00000000..3ff38e40 --- /dev/null +++ b/Hard/Shortest Palindrome.java @@ -0,0 +1,23 @@ +class Solution { + public String shortestPalindrome(String s) { + int n = s.length(); + if (n == 0) { + return s; + } + int left = 0; + for (int right = n - 1; right >= 0; right--) { + if (s.charAt(right) == s.charAt(left)) { + left++; + } + } + if (left == n) { + return s; + } + String nonPalindromeSuffix = s.substring(left); + StringBuilder reverseSuffix = new StringBuilder(nonPalindromeSuffix).reverse(); + return reverseSuffix + .append(shortestPalindrome(s.substring(0, left))) + .append(nonPalindromeSuffix) + .toString(); + } +} diff --git a/Hard/Shortest Path Visiting All Nodes.java b/Hard/Shortest Path Visiting All Nodes.java new file mode 100644 index 00000000..8d08ecfa --- /dev/null +++ b/Hard/Shortest Path Visiting All Nodes.java @@ -0,0 +1,33 @@ +class Solution { + public int shortestPathLength(int[][] graph) { + int n = graph.length; + Map>> map = new HashMap<>(); + Queue queue = new LinkedList<>(); + for (int i = 0; i < n; i++) { + Set visited = new HashSet<>(); + visited.add(i); + map.put(i, new HashSet<>(List.of(visited))); + queue.add(new State(i, 0, visited)); + } + while (!queue.isEmpty()) { + State removed = queue.remove(); + int node = removed.node(); + int steps = removed.steps(); + Set visited = removed.visited(); + if (visited.size() == n) { + return steps; + } + for (int conn : graph[node]) { + Set connVisited = new HashSet<>(visited); + connVisited.add(conn); + if (!map.get(conn).contains(connVisited)) { + queue.add(new State(conn, steps + 1, connVisited)); + map.computeIfAbsent(conn, k -> new HashSet<>()).add(connVisited); + } + } + } + return -1; + } + + private static record State(int node, int steps, Set visited) {} +} diff --git a/Hard/Similar String Groups.java b/Hard/Similar String Groups.java new file mode 100644 index 00000000..50eb13d2 --- /dev/null +++ b/Hard/Similar String Groups.java @@ -0,0 +1,51 @@ +class Solution { + public int numSimilarGroups(String[] strs) { + int n = strs.length; + Map> graph = new HashMap<>(); + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + if (isSimilar(strs[i], strs[j])) { + graph.computeIfAbsent(i, k -> new ArrayList<>()).add(j); + graph.computeIfAbsent(j, k -> new ArrayList<>()).add(i); + } + } + } + boolean[] visited = new boolean[n]; + int count = 0; + for (int i = 0; i < n; i++) { + if (!visited[i]) { + bfs(i, graph, visited); + count++; + } + } + return count; + } + + private boolean isSimilar(String s1, String s2) { + int diff = 0; + for (int i = 0; i < s1.length(); i++) { + if (s1.charAt(i) != s2.charAt(i)) { + diff++; + } + } + return diff == 0 || diff == 2; + } + + private void bfs(int node, Map> graph, boolean[] visited) { + Queue queue = new LinkedList<>(); + queue.add(node); + visited[node] = true; + while (!queue.isEmpty()) { + node = queue.poll(); + if (!graph.containsKey(node)) { + continue; + } + for (int neighbor : graph.get(node)) { + if (!visited[neighbor]) { + visited[neighbor] = true; + queue.add(neighbor); + } + } + } + } +} diff --git a/Hard/Sliding Window Maximum.java b/Hard/Sliding Window Maximum.java index c1ae146e..635720b8 100644 --- a/Hard/Sliding Window Maximum.java +++ b/Hard/Sliding Window Maximum.java @@ -1,23 +1,19 @@ class Solution { - public int[] maxSlidingWindow(int[] nums, int k) { - int n = nums.length; - if (n == 0 || k == 0) { - return new int[0]; + public int[] maxSlidingWindow(int[] nums, int k) { + Deque dequeue = new ArrayDeque<>(); + int[] result = new int[nums.length - k + 1]; + for (int i = 0; i < nums.length; i++) { + if (!dequeue.isEmpty() && dequeue.getFirst() == i - k) { + dequeue.removeFirst(); + } + while (!dequeue.isEmpty() && nums[i] > nums[dequeue.getLast()]) { + dequeue.removeLast(); + } + dequeue.addLast(i); + if (i >= k - 1) { + result[i - k + 1] = nums[dequeue.getFirst()]; + } + } + return result; } - int[] result = new int[n - k + 1]; - Deque deque = new ArrayDeque<>(); - for (int i = 0; i < n; i++) { - while (deque.size() > 0 && deque.peekFirst() <= i - k) { - deque.pollFirst(); - } - while (deque.size() > 0 && nums[deque.peekLast()] < nums[i]) { - deque.pollLast(); - } - deque.offerLast(i); - if (i >= k - 1) { - result[i -k + 1] = nums[deque.peekFirst()]; - } - } - return result; - } } diff --git a/Hard/Sliding Window Median.java b/Hard/Sliding Window Median.java index 944af371..e37c289d 100644 --- a/Hard/Sliding Window Median.java +++ b/Hard/Sliding Window Median.java @@ -1,72 +1,59 @@ class Solution { - List list; - double[] ans; - boolean isEven; - - public double[] medianSlidingWindow(int[] nums, int k) { - list = new ArrayList<>(); - ans = new double[nums.length - k + 1]; - isEven = k % 2 == 0; - - for (int i=0; i list.get(list.size() - 1)) { - return list.size(); - } - - int start = 0; - int end = list.size(); - - while (start < end) { - int mid = (start + end) / 2; - - if (list.get(mid) < num) { - start = mid + 1; - } - else { - end = mid; + public double[] medianSlidingWindow(int[] nums, int windowSize) { + double[] medians = new double[nums.length - windowSize + 1]; + Map delayedRemovals = new HashMap<>(); + PriorityQueue maxHeap = new PriorityQueue<>(Collections.reverseOrder()); + PriorityQueue minHeap = new PriorityQueue<>(); + int currentIndex = 0; + while (currentIndex < windowSize) { + maxHeap.add(nums[currentIndex++]); + } + for (int j = 0; j < windowSize / 2; j++) { + minHeap.add(maxHeap.poll()); + } + int medianIndex = 0; + while (true) { + if (windowSize % 2 == 1) { + medians[medianIndex++] = maxHeap.peek(); + } else { + medians[medianIndex++] = ((double) maxHeap.peek() + (double) minHeap.peek()) / 2.0; } - } - - return end; - } - - private void removeElement(int num) { - for (int i=0; i= nums.length) { break; } + int outNum = nums[currentIndex - windowSize]; + int inNum = nums[currentIndex++]; + int balance = 0; + // Handle outgoing number + balance += (outNum <= maxHeap.peek() ? -1 : 1); + delayedRemovals.put(outNum, delayedRemovals.getOrDefault(outNum, 0) + 1); + // Handle incoming number + if (!maxHeap.isEmpty() && inNum <= maxHeap.peek()) { + balance++; + maxHeap.add(inNum); + } else { + balance--; + minHeap.add(inNum); + } + // Rebalance heaps + if (balance < 0) { + maxHeap.add(minHeap.poll()); + balance++; + } + if (balance > 0) { + minHeap.add(maxHeap.poll()); + balance--; + } + // Remove invalid numbers from the top of the heaps + while (delayedRemovals.getOrDefault(maxHeap.peek(), 0) > 0) { + delayedRemovals.put(maxHeap.peek(), delayedRemovals.get(maxHeap.peek()) - 1); + maxHeap.poll(); + } + while (!minHeap.isEmpty() && delayedRemovals.getOrDefault(minHeap.peek(), 0) > 0) { + delayedRemovals.put(minHeap.peek(), delayedRemovals.get(minHeap.peek()) - 1); + minHeap.poll(); + } } - } - - private double getMedian() { - if (isEven) { - return (double) (list.get(list.size()/2) + list.get(list.size()/2 - 1)) / 2; - } - else { - return (double) list.get(list.size()/2); - } + return medians; } } diff --git a/Hard/Smallest Range Covering Elements from K Lists.java b/Hard/Smallest Range Covering Elements from K Lists.java new file mode 100644 index 00000000..4e814027 --- /dev/null +++ b/Hard/Smallest Range Covering Elements from K Lists.java @@ -0,0 +1,29 @@ +class Solution { + public int[] smallestRange(List> nums) { + PriorityQueue pq = new PriorityQueue<>( + Comparator.comparingInt(a -> a[0])); + int max = Integer.MIN_VALUE; + int start = 0; + int end = Integer.MAX_VALUE; + for (int i = 0; i < nums.size(); i++) { + pq.add(new int[]{nums.get(i).get(0), i, 0}); + max = Math.max(max, nums.get(i).get(0)); + } + while (pq.size() == nums.size()) { + int[] removed = pq.poll(); + int min = removed[0]; + int row = removed[1]; + int col = removed[2]; + if (max - min < end - start) { + start = min; + end = max; + } + if (col + 1 < nums.get(row).size()) { + int next = nums.get(row).get(col + 1); + pq.add(new int[]{next, row, col + 1}); + max = Math.max(max, next); + } + } + return new int[]{start, end}; + } +} diff --git a/Hard/Sort Items by Groups Respecting Dependencies.java b/Hard/Sort Items by Groups Respecting Dependencies.java new file mode 100644 index 00000000..38c531a3 --- /dev/null +++ b/Hard/Sort Items by Groups Respecting Dependencies.java @@ -0,0 +1,62 @@ +class Solution { + public int[] sortItems(int n, int m, int[] group, List> beforeItems) { + int groupId = m; + for (int i = 0; i < group.length; i++) { + if (group[i] == -1) { + group[i] = groupId++; + } + } + Map> nodeToDependentNodes = new HashMap<>(); + Map> groupToDependentGroups = new HashMap<>(); + int[] itemIndegree = new int[n]; + int[] groupIndegree = new int[groupId]; + for (int i = 0; i < beforeItems.size(); i++) { + for (Integer prev : beforeItems.get(i)) { + nodeToDependentNodes.computeIfAbsent(prev, k -> new ArrayList<>()).add(i); + itemIndegree[i]++; + if (group[i] != group[prev]) { + groupToDependentGroups.computeIfAbsent(group[prev], k -> new ArrayList<>()).add(group[i]); + groupIndegree[group[i]]++; + } + } + } + List itemOrdering = topologicalSort(nodeToDependentNodes, itemIndegree); + List groupOrdering = topologicalSort(groupToDependentGroups, groupIndegree); + if (itemOrdering.isEmpty() || groupOrdering.isEmpty()) { + return new int[]{}; + } + Map> orderedGroups = new HashMap<>(); + for (Integer item : itemOrdering) { + orderedGroups.computeIfAbsent(group[item], k -> new ArrayList<>()).add(item); + } + int[] result = new int[n]; + int idx = 0; + for (Integer groupNo : groupOrdering) { + for (Integer item : orderedGroups.getOrDefault(groupNo, new ArrayList<>())) { + result[idx++] = item; + } + } + return result; + } + + private static List topologicalSort(Map> graph, int[] indegree) { + List visited = new ArrayList<>(); + Queue queue = new LinkedList<>(); + for (int i = 0; i < indegree.length; i++) { + if (indegree[i] == 0) { + queue.add(i); + } + } + while (!queue.isEmpty()) { + int removed = queue.remove(); + visited.add(removed); + for (Integer conn : graph.getOrDefault(removed, new ArrayList<>())) { + indegree[conn]--; + if (indegree[conn] == 0) { + queue.add(conn); + } + } + } + return visited.size() == indegree.length ? visited : new ArrayList<>(); + } +} diff --git a/Hard/Stamping The Sequence.java b/Hard/Stamping The Sequence.java new file mode 100644 index 00000000..1d472157 --- /dev/null +++ b/Hard/Stamping The Sequence.java @@ -0,0 +1,50 @@ +class Solution { + public int[] movesToStamp(String stamp, String target) { + char[] stampLetters = stamp.toCharArray(); + char[] targetLetters = target.toCharArray(); + List result = new ArrayList<>(); + boolean[] visited = new boolean[target.length()]; + int count = 0; + while (count < target.length()) { + boolean replace = false; + for (int i = 0; i <= target.length() - stamp.length(); i++) { + if (!visited[i] && isReplacePossible(stampLetters, targetLetters, i)) { + count = performStamping(targetLetters, i, stamp.length(), count); + replace = true; + visited[i] = true; + result.add(i); + if (count == targetLetters.length) { + break; + } + } + } + if (!replace) { + return new int[0]; + } + } + int[] resArray = new int[result.size()]; + for (int i = 0; i < result.size(); i++) { + resArray[i] = result.get(result.size() - i - 1); + } + return resArray; + } + + private boolean isReplacePossible(char[] stampLetters, char[] targetLetters, int idx) { + for (int i = 0; i < stampLetters.length; i++) { + if (targetLetters[i + idx] != '*' && targetLetters[i + idx] != stampLetters[i]) { + return false; + } + } + return true; + } + + private int performStamping(char[] targetLetters, int idx, int stampLength, int count) { + for (int i = 0; i < stampLength; i++) { + if (targetLetters[i + idx] != '*') { + targetLetters[i + idx] = '*'; + count++; + } + } + return count; + } +} diff --git a/Hard/Stone Game III.java b/Hard/Stone Game III.java new file mode 100644 index 00000000..0ee4e539 --- /dev/null +++ b/Hard/Stone Game III.java @@ -0,0 +1,16 @@ +class Solution { + public String stoneGameIII(int[] stoneValue) { + int n = stoneValue.length; + int[] dp = new int[n + 1]; + for (int i = n - 1; i >= 0; i--) { + dp[i] = stoneValue[i] - dp[i + 1]; + if (i + 2 <= n) { + dp[i] = Math.max(dp[i], stoneValue[i] + stoneValue[i + 1] - dp[i + 2]); + } + if (i + 3 <= n) { + dp[i] = Math.max(dp[i], stoneValue[i] + stoneValue[i + 1] + stoneValue[i + 2] - dp[i + 3]); + } + } + return dp[0] == 0 ? "Tie" : (dp[0] > 0 ? "Alice" : "Bob"); + } +} diff --git a/Hard/Stream of Characters.java b/Hard/Stream of Characters.java index 02fe377a..2f3fbed7 100644 --- a/Hard/Stream of Characters.java +++ b/Hard/Stream of Characters.java @@ -1,19 +1,23 @@ class StreamChecker { - TrieNode root; + Deque stream; + TrieNode root; public StreamChecker(String[] words) { root = new TrieNode('-'); - stream = new ArrayDeque(); - for (String word : words) { - TrieNode curr = root; - for (int i = word.length() - 1; i >= 0; i--) { - if (!curr.map.containsKey(word.charAt(i))) { - curr.map.put(word.charAt(i), new TrieNode(word.charAt(i))); - } - curr = curr.map.get(word.charAt(i)); + stream = new ArrayDeque<>(); + Arrays.stream(words).forEach(word -> addWord(word)); + } + + public void addWord(String word) { + TrieNode curr = root; + for (int i = word.length() - 1; i >= 0; i--) { + char c = word.charAt(i); + if (curr.children[c - 'a'] == null) { + curr.children[c - 'a'] = new TrieNode(c); } - curr.isWord = true; + curr = curr.children[c - 'a']; } + curr.isWord = true; } public boolean query(char letter) { @@ -23,25 +27,24 @@ public boolean query(char letter) { if (curr.isWord) { return true; } - if (!curr.map.containsKey(c)) { + if (curr.children[c - 'a'] == null) { return false; } - curr = curr.map.get(c); + curr = curr.children[c - 'a']; } return curr.isWord; } -} - - -class TrieNode { - char c; - Map map; - boolean isWord; - public TrieNode(char c) { - this.c = c; - map = new HashMap<>(); - isWord = false; + + class TrieNode { + char c; + TrieNode[] children; + boolean isWord; + + public TrieNode(char c) { + this.c = c; + children = new TrieNode[26]; + } } } diff --git a/Hard/String Compression II.java b/Hard/String Compression II.java new file mode 100644 index 00000000..ac420adf --- /dev/null +++ b/Hard/String Compression II.java @@ -0,0 +1,58 @@ +class Solution { + + private static int[][][][] dp = new int[100][101][100][26]; + + public int getLengthOfOptimalCompression(String s, int k) { + int n = s.length(); + for (int i = 0; i < n; i++) { + for (int j = 0; j <= k; j++) { + for (int x = 0; x < n; x++) { + for (int y = 0; y < 26; y++) { + dp[i][j][x][y] = -1; + } + } + } + } + return solver(s.toCharArray(), 0, k, 0, s.charAt(0)); + } + + private int solver(char[] letters, int idx, int k, int currFrequency, char prevChar) { + if (idx == letters.length) { + return getLetterCount(currFrequency); + } + if (dp[idx][k][currFrequency][prevChar - 'a'] != -1) { + return dp[idx][k][currFrequency][prevChar - 'a']; + } + int result = 0; + if (letters[idx] == prevChar) { + result = k == 0 ? + solver(letters, idx + 1, k, currFrequency + 1, prevChar) : + Math.min( + solver(letters, idx + 1, k , currFrequency + 1, prevChar), // don't delete + solver(letters, idx + 1, k - 1 , currFrequency, prevChar) // delete + ); + } else { + result = k == 0 ? + getLetterCount(currFrequency) + solver(letters, idx + 1, k, 1, letters[idx]) : + Math.min( + getLetterCount(currFrequency) + solver(letters, idx + 1, k, 1, letters[idx]), // don't delete + solver(letters, idx + 1, k - 1, currFrequency, prevChar) // delete + ); + } + return dp[idx][k][currFrequency][prevChar - 'a'] = result; + } + + private static int getLetterCount(int frequency) { + if (frequency == 0) { + return 0; + } + int digits = 1; + if (frequency > 9) { + digits = 2; + } + if (frequency > 99) { + digits = 3; + } + return frequency == 1 ? 1 : (digits + 1); + } +} diff --git a/Hard/Subarrays with K Different Integers.java b/Hard/Subarrays with K Different Integers.java index 42224709..0a1d5559 100644 --- a/Hard/Subarrays with K Different Integers.java +++ b/Hard/Subarrays with K Different Integers.java @@ -1,29 +1,23 @@ class Solution { - public int subarraysWithKDistinct(int[] A, int K) { - return atMostK(A, K) - atMostK(A, K - 1); - } - - private int atMostK(int[] A, int K) { - int start = 0; - int end = 0; - int n = A.length; - Map map = new HashMap<>(); - int count = 0; - while (end < n) { - if (map.getOrDefault(A[end], 0) == 0) { - K--; - } - map.put(A[end], map.getOrDefault(A[end], 0) + 1); - while (K < 0) { - map.put(A[start], map.getOrDefault(A[start], 0) - 1); - if (map.get(A[start]) == 0) { - K++; + public int subarraysWithKDistinct(int[] nums, int k) { + return slidingWindowAtMost(nums, k) - slidingWindowAtMost(nums, k - 1); + } + + private int slidingWindowAtMost(int[] nums, int k) { + Map map = new HashMap<>(); + int left = 0; + int count = 0; + for (int right = 0; right < nums.length; right++) { + map.put(nums[right], map.getOrDefault(nums[right], 0) + 1); + while (map.size() > k) { + map.put(nums[left], map.get(nums[left]) - 1); + if (map.get(nums[left]) == 0) { + map.remove(nums[left]); + } + left++; + } + count += right - left + 1; } - start++; - } - count += end - start + 1; - end++; + return count; } - return count; - } } diff --git a/Hard/Substring with Concatenation of All Words.java b/Hard/Substring with Concatenation of All Words.java index 1af85664..5dcfd8bc 100644 --- a/Hard/Substring with Concatenation of All Words.java +++ b/Hard/Substring with Concatenation of All Words.java @@ -1,39 +1,53 @@ class Solution { public List findSubstring(String s, String[] words) { - if (s.length() == 0 || words.length == 0) { - return new ArrayList<>(); - } - Map wordFreqMap = new HashMap<>(); + int numberOfWords = words.length; + int singleWordLength = words[0].length(); + int totalSubstringLength = singleWordLength * numberOfWords; + Map wordCount = new HashMap<>(); for (String word : words) { - wordFreqMap.put(word, wordFreqMap.getOrDefault(word, 0) + 1); + wordCount.put(word, wordCount.getOrDefault(word, 0) + 1); } - int stringLength = s.length(); - int wordCount = words.length; - int singleWordLength = words[0].length(); - List indices = new ArrayList<>(); - for (int i = 0; i + singleWordLength * wordCount <= stringLength; i++) { - if (match(s, i, singleWordLength, wordFreqMap, wordCount)) { - indices.add(i); - } + List result = new ArrayList<>(); + for (int i = 0; i < singleWordLength; i++) { + slidingWindow(i, s, result, singleWordLength, totalSubstringLength, wordCount, numberOfWords); } - return indices; + return result; } - - private boolean match(String s, int start, int singleWordLength, Map wordFreqMap, int wordCount) { - Map currFreqMap = new HashMap<>(); - for (int i = 0; i < wordCount; i++) { - String currWord = s.substring(start + i * singleWordLength, start + (i + 1) * singleWordLength); - Integer freq = wordFreqMap.get(currWord); - // Word not in required words - if (freq == null) { - return false; - } - currFreqMap.put(currWord, currFreqMap.getOrDefault(currWord, 0) + 1); - // Word occurs more than the required count - if (currFreqMap.get(currWord) > freq) { - return false; + + private void slidingWindow(int left, String s, List answer, int singleWordLength, + int totalSubstringLength, Map wordCount, int numberOfWords) { + Map wordsFound = new HashMap<>(); + int wordsUsed = 0; + boolean excessWord = false; + int n = s.length(); + for (int right = left; right <= n - singleWordLength; right += singleWordLength) { + String currSubstring = s.substring(right, right + singleWordLength); + if (!wordCount.containsKey(currSubstring)) { + wordsFound.clear(); + wordsUsed = 0; + excessWord = false; + left = right + singleWordLength; + } else { + while (right - left == totalSubstringLength || excessWord) { + String leftmostWord = s.substring(left, left + singleWordLength); + left += singleWordLength; + wordsFound.put(leftmostWord, wordsFound.get(leftmostWord) - 1); + if (wordsFound.get(leftmostWord) >= wordCount.get(leftmostWord)) { + excessWord = false; + } else { + wordsUsed--; + } + } + wordsFound.put(currSubstring, wordsFound.getOrDefault(currSubstring, 0) + 1); + if (wordsFound.get(currSubstring) <= wordCount.get(currSubstring)) { + wordsUsed++; + } else { + excessWord = true; + } + if (wordsUsed == numberOfWords && !excessWord) { + answer.add(left); + } } } - return true; } } diff --git a/Hard/Tallest Billboard.java b/Hard/Tallest Billboard.java new file mode 100644 index 00000000..04f81763 --- /dev/null +++ b/Hard/Tallest Billboard.java @@ -0,0 +1,35 @@ +class Solution { + public int tallestBillboard(int[] rods) { + int n = rods.length; + Map firstHalf = helper(rods, 0, n / 2); + Map secondHalf = helper(rods, n / 2, n); + int result = 0; + for (Integer difference : firstHalf.keySet()) { + if (secondHalf.containsKey(-1 * difference)) { + result = Math.max(result, firstHalf.get(difference) + secondHalf.get(-1 * difference)); + } + } + return result; + } + + private Map helper(int[] rods, int leftIdx, int rightIdx) { + Set> states = new HashSet<>(); + states.add(new Pair(0, 0)); + for (int i = leftIdx; i < rightIdx; i++) { + int rod = rods[i]; + Set> newStates = new HashSet<>(); + for (Pair state : states) { + newStates.add(new Pair(state.getKey() + rod, state.getValue())); + newStates.add(new Pair(state.getKey(), state.getValue() + rod)); + } + states.addAll(newStates); + } + Map dp = new HashMap<>(); + for (Pair pair : states) { + Integer left = pair.getKey(); + Integer right = pair.getValue(); + dp.put(left - right, Math.max(dp.getOrDefault(left - right, 0), left)); + } + return dp; + } +} diff --git a/Hard/The Skyline Problem.java b/Hard/The Skyline Problem.java new file mode 100644 index 00000000..92c9e516 --- /dev/null +++ b/Hard/The Skyline Problem.java @@ -0,0 +1,27 @@ +class Solution { + public List> getSkyline(int[][] buildings) { + List> result = new ArrayList<>(); + List heights = new ArrayList<>(); + for (int[] building : buildings) { + heights.add(new int[]{building[0], -1 * building[2]}); + heights.add(new int[]{building[1], 1 * building[2]}); + } + Collections.sort(heights, (a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]); + PriorityQueue pq = new PriorityQueue<>((a, b) -> b - a); + pq.add(0); + int previousMax = 0; + for (int[] height : heights) { + if (height[1] < 0) { + pq.add(-1 * height[1]); + } else { + pq.remove(height[1]); + } + int currentMax = pq.peek(); + if (currentMax != previousMax) { + result.add(Arrays.asList(height[0], currentMax)); + previousMax = currentMax; + } + } + return result; + } +} diff --git a/Hard/Trapping Rain Water.java b/Hard/Trapping Rain Water.java index 6abc9416..263ab08a 100644 --- a/Hard/Trapping Rain Water.java +++ b/Hard/Trapping Rain Water.java @@ -1,20 +1,23 @@ class Solution { - public int trap(int[] A) { - Stack stack = new Stack(); - int i = 0; - int maxWater = 0; - - while (i < A.length){ - if (stack.isEmpty() || A[i] <= A[stack.peek()]){ - stack.push(i++); - } - else { - int bot = stack.pop(); - maxWater += stack.isEmpty() ? 0 : - (Math.min(A[stack.peek()], A[i]) - A[bot]) * (i - stack.peek() - 1); - } + public int trap(int[] height) { + if (height.length == 0) { + return 0; } - - return maxWater; + int n = height.length; + int[] leftMax = new int[n]; + leftMax[0] = height[0]; + for (int i = 1; i < n; i++) { + leftMax[i] = Math.max(height[i], leftMax[i - 1]); + } + int[] rightMax = new int[n]; + rightMax[n - 1] = height[n - 1]; + for (int i = n - 2; i >= 0; i--) { + rightMax[i] = Math.max(rightMax[i + 1], height[i]); + } + int result = 0; + for (int i = 1; i < n - 1; i++) { + result += Math.min(leftMax[i], rightMax[i]) - height[i]; + } + return result; } } diff --git a/Hard/Valid Number.java b/Hard/Valid Number.java index d9a68285..1cdebfa8 100644 --- a/Hard/Valid Number.java +++ b/Hard/Valid Number.java @@ -1,90 +1,62 @@ class Solution { - public boolean isNumber(String s) { - s = s.trim(); - char[] ch = s.toCharArray(); + public boolean isNumber(String s) { int idx = 0; - int n = ch.length; - boolean signFound = false; - boolean decimalFound = false; - boolean numFound = false; - boolean expoFound = false; - + boolean isDecimal = false; + boolean isDigit = false; + boolean digitsBeforeDecimal = false; + boolean digitsAfterDecimal = false; + int n = s.length(); + if (s.charAt(idx) == '-' || s.charAt(idx) == '+') { + idx++; + } while (idx < n) { - if (ch[idx] == '+' || ch[idx] == '-') { - if (numFound || signFound || decimalFound) { + if (s.charAt(idx) == '.') { + if (isDecimal) { return false; } - - signFound = true; - } - else if (ch[idx] == '.') { - if (decimalFound) { + isDecimal = true; + } else if (s.charAt(idx) == 'e' || s.charAt(idx) == 'E') { + if (!isDigit) { return false; } - decimalFound = true; - } - else if (Character.isLetter(ch[idx])) { - if (ch[idx] == 'e') { - if (!numFound) { - return false; - } - idx++; - expoFound = true; - break; - } - else { + boolean valid = isValidExponent(s, idx + 1); + if (!valid) { return false; } - } - else if (Character.isDigit(ch[idx])) { - numFound = true; - } - else if (ch[idx] == ' ') { - if (numFound || signFound || decimalFound) { - return false; + break; + } else if (Character.isDigit(s.charAt(idx))) { + if (isDecimal) { + digitsAfterDecimal = true; + } else { + digitsBeforeDecimal = true; } + isDigit = true; + } else { + return false; } - idx++; } - - if (!numFound) { - return false; + if (isDecimal) { + return digitsBeforeDecimal || digitsAfterDecimal; } + return isDigit; + } - if (expoFound && idx == n) { + private boolean isValidExponent(String s, int idx) { + if (idx == s.length()) { return false; } - - signFound = false; - numFound = false; - while (idx < n) { - if (ch[idx] == '.') { - return false; - } - else if (ch[idx] == '+' || ch[idx] == '-') { - if (signFound) { - return false; - } - if (numFound) { - return false; - } - signFound = true; - } - else if (Character.isDigit(ch[idx])) { - numFound = true; - } - else { + if (s.charAt(idx) == '-' || s.charAt(idx) == '+') { + idx++; + } + boolean digitFound = false; + while (idx < s.length()) { + if (!Character.isDigit(s.charAt(idx))) { return false; } - + digitFound = true; idx++; } - - if (expoFound && !numFound) { - return false; - } - - return true; + return digitFound; } } diff --git a/Hard/Valid Palindrome III.java b/Hard/Valid Palindrome III.java new file mode 100644 index 00000000..dc97a304 --- /dev/null +++ b/Hard/Valid Palindrome III.java @@ -0,0 +1,26 @@ +class Solution { + public boolean isValidPalindrome(String s, int k) { + int n = s.length(); + Integer[][] dp = new Integer[n][n]; + return isValidPalindrome(s, 0, n - 1, dp) <= k; + } + + private int isValidPalindrome(String s, int left, int right, Integer[][] dp) { + if (left == right) { + return 0; + } + if (left == right - 1) { + return s.charAt(left) != s.charAt(right) ? 1 : 0; + } + if (dp[left][right] != null) { + return dp[left][right]; + } + if (s.charAt(left) == s.charAt(right)) { + return isValidPalindrome(s, left + 1, right - 1, dp); // move both pointers + } + return dp[left][right] = 1 + Math.min( + isValidPalindrome(s, left + 1, right, dp), // move only left pointer + isValidPalindrome(s, left, right - 1, dp) // move only right pointer + ); + } +} diff --git a/Hard/Vertical Order Traversal Of a Binary Tree.java b/Hard/Vertical Order Traversal Of a Binary Tree.java new file mode 100644 index 00000000..2c82d9f6 --- /dev/null +++ b/Hard/Vertical Order Traversal Of a Binary Tree.java @@ -0,0 +1,60 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public List> verticalTraversal(TreeNode root) { + Map> map = new HashMap<>(); + Queue queue = new LinkedList<>(); + queue.add(new NodePair(0, 0, root)); + int minColumn = 0; + int maxColumn = 0; + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + NodePair removed = queue.remove(); + minColumn = Math.min(minColumn, removed.y); + maxColumn = Math.max(maxColumn, removed.y); + map.computeIfAbsent(removed.y, k -> new ArrayList<>()).add(removed); + if (removed.node.left != null) { + queue.add(new NodePair(removed.x + 1, removed.y - 1, removed.node.left)); + } + if (removed.node.right != null) { + queue.add(new NodePair(removed.x + 1, removed.y + 1, removed.node.right)); + } + } + } + List> result = new ArrayList<>(); + for (int key = minColumn; key <= maxColumn; key++) { + List list = map.get(key); + result.add(list.stream() + .sorted(Comparator.comparingInt((NodePair o) -> o.x).thenComparingInt(o -> o.node.val)) + .map(np -> np.node.val) + .collect(Collectors.toList())); + } + return result; + } + + class NodePair { + int x; + int y; + TreeNode node; + + public NodePair(int x, int y, TreeNode node) { + this.x = x; + this.y = y; + this.node = node; + } + } +} diff --git a/Hard/Wildcard Matching.java b/Hard/Wildcard Matching.java new file mode 100644 index 00000000..993a9f62 --- /dev/null +++ b/Hard/Wildcard Matching.java @@ -0,0 +1,32 @@ +class Solution { + public boolean isMatch(String s, String p) { + int sLen = s.length(); + int pLen = p.length(); + int sIdx = 0; + int pIdx = 0; + int startIdx = -1; + int sTempIdx = -1; + while (sIdx < sLen) { + if (pIdx < pLen && (p.charAt(pIdx) == '?' || p.charAt(pIdx) == s.charAt(sIdx))) { + sIdx++; + pIdx++; + } else if (pIdx < pLen && p.charAt(pIdx) == '*') { + startIdx = pIdx; + sTempIdx = sIdx; + pIdx++; + } else if (startIdx == -1) { + return false; + } else { + pIdx = startIdx + 1; + sIdx = sTempIdx + 1; + sTempIdx = sIdx; + } + } + for (int i = pIdx; i < pLen; i++) { + if (p.charAt(i) != '*') { + return false; + } + } + return true; + } +} diff --git a/Hard/Word Search II.java b/Hard/Word Search II.java index 4fd55b93..3e9ce51a 100644 --- a/Hard/Word Search II.java +++ b/Hard/Word Search II.java @@ -1,66 +1,60 @@ class Solution { - public List findWords(char[][] board, String[] words) { - List result = new ArrayList<>(); - TrieNode root = buildTrie(words); - - for (int i = 0; i < board.length; i++) { - for (int j = 0; j < board[0].length; j++) { - helper(board, i, j, root, result); - } + + private final int[][] DIRS = {{1, 0}, {0, 1}, {0, -1}, {-1, 0}}; + + public List findWords(char[][] board, String[] words) { + TrieNode root = new TrieNode(); + for (String word : words) { + TrieNode node = root; + for (Character letter : word.toCharArray()) { + if (node.children.containsKey(letter)) { + node = node.children.get(letter); + } else { + TrieNode newNode = new TrieNode(); + node.children.put(letter, newNode); + node = newNode; } - - return result; + } + node.word = word; } - - private void helper(char[][] board, int i, int j, TrieNode root, List result) { - if (i < 0 || i >= board.length || j >= board[i].length || j < 0) { - return; + List result = new ArrayList<>(); + for (int row = 0; row < board.length; ++row) { + for (int col = 0; col < board[row].length; ++col) { + if (root.children.containsKey(board[row][col])) { + backtracking(row, col, root, result, board); } - - char c = board[i][j]; - if (c == '@' || root.next[c - 'a'] == null) { - return; - } - - root = root.next[c - 'a']; - if (root.word != null) { - result.add(root.word); - root.word = null; - } - - // Choose - board[i][j] = '@'; - - // Explore - helper(board, i + 1, j, root, result); - helper(board, i, j + 1, root, result); - helper(board, i, j - 1, root, result); - helper(board, i - 1, j, root, result); - - // Un-choose - board[i][j] = c; + } } - - private TrieNode buildTrie(String[] words) { - TrieNode root = new TrieNode(); - for (String word : words) { - TrieNode temp =root; - for (char c : word.toCharArray()) { - if (temp.next[c - 'a'] == null) { - temp.next[c - 'a'] = new TrieNode(); - } - - temp = temp.next[c - 'a']; - } - - temp.word = word; - } - - return root; + return result; + } + + private void backtracking(int row, int col, TrieNode parent, List result, char[][] board) { + char letter = board[row][col]; + TrieNode currNode = parent.children.get(letter); + if (currNode.word != null) { + result.add(currNode.word); + currNode.word = null; + } + board[row][col] = '#'; + for (int[] dir : DIRS) { + int newRow = row + dir[0]; + int newCol = col + dir[1]; + if (newRow < 0 || newRow >= board.length || newCol < 0 || newCol >= board[0].length) { + continue; + } + if (currNode.children.containsKey(board[newRow][newCol])) { + backtracking(newRow, newCol, currNode, result, board); + } } - - class TrieNode { - TrieNode[] next = new TrieNode[26]; - String word; + board[row][col] = letter; + if (currNode.children.isEmpty()) { + parent.children.remove(letter); } + } + + private class TrieNode { + Map children = new HashMap(); + String word = null; + public TrieNode() {} + } } diff --git a/Medium/01 Matrix.java b/Medium/01 Matrix.java index 8892b6fc..1faa99d0 100644 --- a/Medium/01 Matrix.java +++ b/Medium/01 Matrix.java @@ -1,40 +1,33 @@ -public class Solution { - public int[][] updateMatrix(int[][] matrix) { - int m = matrix.length; - int n = matrix[0].length; - - Queue queue = new LinkedList<>(); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - if (matrix[i][j] == 0) { - queue.offer(new int[] {i, j}); - } - else { - matrix[i][j] = Integer.MAX_VALUE; - } - } +class Solution { + private static final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + + public int[][] updateMatrix(int[][] mat) { + int numRows = mat.length; + int numCols = mat[0].length; + int[][] distances = new int[numRows][numCols]; + Queue queue = new LinkedList<>(); + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numCols; j++) { + if (mat[i][j] == 0) { + queue.add(new int[]{i, j}); + } else { + distances[i][j] = Integer.MAX_VALUE; } - - int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; - - while (!queue.isEmpty()) { - int[] cell = queue.poll(); - for (int[] d : dirs) { - int r = cell[0] + d[0]; - int c = cell[1] + d[1]; - if (r < 0 || - r >= m || - c < 0 || - c >= n || - matrix[r][c] <= matrix[cell[0]][cell[1]] + 1) { - continue; - } - - queue.add(new int[] {r, c}); - matrix[r][c] = matrix[cell[0]][cell[1]] + 1; - } + } + } + while (!queue.isEmpty()) { + int[] removed = queue.remove(); + int currX = removed[0]; + int currY = removed[1]; + for (int[] dir : DIRS) { + int newX = currX + dir[0]; + int newY = currY + dir[1]; + if (newX >= 0 && newY >= 0 && newX < numRows && newY < numCols && distances[newX][newY] > distances[currX][currY] + 1) { + queue.add(new int[]{newX, newY}); + distances[newX][newY] = distances[currX][currY] + 1; } - - return matrix; + } } + return distances; + } } diff --git a/Medium/132 Pattern.java b/Medium/132 Pattern.java index 33d16450..54937149 100644 --- a/Medium/132 Pattern.java +++ b/Medium/132 Pattern.java @@ -1,25 +1,23 @@ class Solution { - public boolean find132pattern(int[] nums) { - if (nums.length < 3) { - return false; - } - Stack stack = new Stack<>(); - int[] min = new int[nums.length]; - min[0] = nums[0]; - for (int i = 1; i < nums.length; i++) { - min[i] = Math.min(min[i - 1], nums[i]); - } - for (int i = nums.length - 1; i >= 0; i--) { - if (nums[i] > min[i]) { // Consider nums[i] as 3 and min[i] as 1 - while (!stack.isEmpty() && stack.peek() <= min[i]) { // Search for 2 - stack.pop(); + public boolean find132pattern(int[] nums) { + int n = nums.length; + int[] uptoIdxMin = new int[n]; + uptoIdxMin[0] = nums[0]; + for (int i = 1; i < n; i++) { + uptoIdxMin[i] = Math.min(uptoIdxMin[i - 1], nums[i]); } - if (!stack.isEmpty() && stack.peek() < nums[i]) { // If 2 found - return true; + Stack stack = new Stack<>(); + for (int i = n - 1; i >= 0; i--) { + if (nums[i] > uptoIdxMin[i]) { + while (!stack.isEmpty() && stack.peek() <= uptoIdxMin[i]) { + stack.pop(); + } + if (!stack.isEmpty() && stack.peek() < nums[i]) { + return true; + } + stack.push(nums[i]); + } } - stack.push(nums[i]); - } + return false; } - return false; - } } diff --git a/Medium/3Sum Closest.java b/Medium/3Sum Closest.java index ed469e0e..7520f9ea 100644 --- a/Medium/3Sum Closest.java +++ b/Medium/3Sum Closest.java @@ -1,27 +1,22 @@ class Solution { - public int threeSumClosest(int[] nums, int target) { - int sum = Integer.MAX_VALUE; - Arrays.sort(nums); - - for (int i=0; i Math.abs(target - tempSum)) { - sum = tempSum; - } - - if (tempSum > target) { - k--; - } - else { - j++; - } - } + public int threeSumClosest(int[] nums, int target) { + Arrays.sort(nums); + int closestDiff = Integer.MAX_VALUE; + for (int i = 0; i < nums.length; i++) { + int start = i + 1; + int end = nums.length - 1; + while (start < end) { + int currSum = nums[i] + nums[start] + nums[end]; + if (Math.abs(target - currSum) < Math.abs(closestDiff)) { + closestDiff = target - currSum; } - - return sum; + if (currSum < target) { + start++; + } else { + end--; + } + } } + return target - closestDiff; + } } diff --git a/Medium/3Sum With Multiplicity.java b/Medium/3Sum With Multiplicity.java new file mode 100644 index 00000000..ca9315b3 --- /dev/null +++ b/Medium/3Sum With Multiplicity.java @@ -0,0 +1,37 @@ +class Solution { + public int threeSumMulti(int[] nums, int target) { + Arrays.sort(nums); + long answer = 0; + for (int i = 0; i < nums.length; i++) { + int updatedTarget = target - nums[i]; + int startIdx = i + 1; + int endIdx = nums.length - 1; + while (startIdx < endIdx) { + if (nums[startIdx] + nums[endIdx] < updatedTarget) { + startIdx++; + } else if (nums[startIdx] + nums[endIdx] > updatedTarget) { + endIdx--; + } else if (nums[startIdx] != nums[endIdx]) { + int leftIdx = 1; + int rightIdx = 1; + while (startIdx + 1 < endIdx && nums[startIdx] == nums[startIdx + 1]) { + leftIdx++; + startIdx++; + } + while (endIdx - 1 > startIdx && nums[endIdx] == nums[endIdx - 1]) { + rightIdx++; + endIdx--; + } + + answer = (answer + leftIdx * rightIdx) % 1000000007; + startIdx++; + endIdx--; + } else { + answer = (answer + ((endIdx - startIdx + 1) * (endIdx - startIdx) / 2)) % 1000000007; + break; + } + } + } + return (int) answer; + } +} diff --git a/Medium/3Sum.java b/Medium/3Sum.java index e959d745..3c615e51 100644 --- a/Medium/3Sum.java +++ b/Medium/3Sum.java @@ -1,29 +1,25 @@ class Solution { - public List> threeSum(int[] nums) { - Arrays.sort(nums); - List> list = new ArrayList<>(); - for (int i = 0; i < nums.length && nums[i] <= 0; i++) { - if (i == 0 || nums[i - 1] != nums[i]) { - twoSumHelper(nums, i, list); - } + public List> threeSum(int[] nums) { + Arrays.sort(nums); + List> result = new ArrayList<>(); + for (int i = 0; i < nums.length; i++) { + if (i != 0 && nums[i] == nums[i - 1]) { + continue; + } + int low = i + 1; + int high = nums.length - 1; + while (low < high) { + int currSum = nums[low] + nums[high] + nums[i]; + if (currSum > 0 || (high < nums.length - 1 && nums[high] == nums[high + 1])) { + high--; + } else if (currSum < 0 || (low > i + 1 && nums[low] == nums[low - 1])) { + low++; + } else { + result.add(Arrays.asList(nums[i], nums[low++], nums[high--])); + } + + } + } + return result; } - return list; - } - - private void twoSumHelper(int[] nums, int i, List> list) { - int low = i + 1; - int high = nums.length - 1; - while (low < high) { - int sum = nums[i] + nums[low] + nums[high]; - if (sum < 0 || (low > i + 1 && nums[low] == nums[low - 1])) { - low++; - } - else if (sum > 0 || (high < nums.length - 1 && nums[high] == nums[high + 1])) { - high--; - } - else { - list.add(Arrays.asList(nums[i], nums[low++], nums[high--])); - } - } - } } diff --git a/Medium/4 Keys Keyboard.java b/Medium/4 Keys Keyboard.java new file mode 100644 index 00000000..2ca4bb8e --- /dev/null +++ b/Medium/4 Keys Keyboard.java @@ -0,0 +1,14 @@ +class Solution { + public int maxA(int n) { + int[] dp = new int[n + 1]; + for (int i = 0; i <= n; i++) { + dp[i] = i; + } + for (int i = 0; i <= n - 3; i++) { + for (int j = i + 3; j <= Math.min(n, i + 6); j++) { + dp[j] = Math.max(dp[j], (j - i - 1) * dp[i]); + } + } + return dp[n]; + } +} diff --git a/Medium/4Sum II.java b/Medium/4Sum II.java new file mode 100644 index 00000000..ecd8f47b --- /dev/null +++ b/Medium/4Sum II.java @@ -0,0 +1,18 @@ +class Solution { + public int fourSumCount(int[] A, int[] B, int[] C, int[] D) { + int n = A.length; + Map map = new HashMap<>(); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + map.put(A[i] + B[j], map.getOrDefault(A[i] + B[j], 0) + 1); + } + } + int count = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + count += map.getOrDefault(-1 * (C[i] + D[j]), 0); + } + } + return count; + } +} diff --git a/Medium/4Sum.java b/Medium/4Sum.java index 41f71e4a..50832c2c 100644 --- a/Medium/4Sum.java +++ b/Medium/4Sum.java @@ -1,25 +1,46 @@ class Solution { public List> fourSum(int[] nums, int target) { Arrays.sort(nums); - Set> set = new HashSet<>(); - for (int i = 0; i < nums.length; i++) { - for (int j = i + 1; j < nums.length; j++) { - int newTarget = target - nums[i] - nums[j]; - int start = j + 1; - int end = nums.length - 1; - while (start < end) { - if ((nums[start] + nums[end]) == newTarget) { - set.add(Arrays.asList(nums[i], nums[j], nums[start++], nums[end--])); - } - else if ((nums[start] + nums[end]) < newTarget) { - start++; - } - else { - end--; - } + return kSum(nums, target, 0, 4); + } + + public List> kSum(int[] nums, long target, int start, int k) { + List> result = new ArrayList<>(); + if (start == nums.length) { + return result; + } + long averageValue = target / k; + if (nums[start] > averageValue || averageValue > nums[nums.length - 1]) { + return result; + } + if (k == 2) { + return twoSum(nums, target, start); + } + for (int i = start; i < nums.length; ++i) { + if (i == start || nums[i - 1] != nums[i]) { + for (List subset : kSum(nums, target - nums[i], i + 1, k - 1)) { + result.add(new ArrayList<>(Arrays.asList(nums[i]))); + result.get(result.size() - 1).addAll(subset); } } } - return new ArrayList<>(set); + return result; + } + + public List> twoSum(int[] nums, long target, int start) { + List> result = new ArrayList<>(); + int low = start; + int high = nums.length - 1; + while (low < high) { + int currSum = nums[low] + nums[high]; + if (currSum < target || (low > start && nums[low] == nums[low - 1])) { + ++low; + } else if (currSum > target || (high < nums.length - 1 && nums[high] == nums[high + 1])) { + --high; + } else { + result.add(Arrays.asList(nums[low++], nums[high--])); + } + } + return result; } } diff --git a/Medium/Accounts Merge.java b/Medium/Accounts Merge.java index caa718e8..97b55568 100644 --- a/Medium/Accounts Merge.java +++ b/Medium/Accounts Merge.java @@ -1,38 +1,38 @@ class Solution { public List> accountsMerge(List> accounts) { - Map emailToNameMap = new HashMap<>(); - Map> graph = new HashMap<>(); + Map> adjacencyList = new HashMap<>(); for (List account : accounts) { - String name = account.get(0); - for (int i = 1; i < account.size(); i++) { - emailToNameMap.put(account.get(i), name); - graph.computeIfAbsent(account.get(i), k -> new HashSet<>()).add(account.get(1)); - graph.computeIfAbsent(account.get(1), k -> new HashSet<>()).add(account.get(i)); + String firstEmail = account.get(1); + for (int i = 2; i < account.size(); i++) { + adjacencyList.computeIfAbsent(firstEmail, k -> new ArrayList<>()).add(account.get(i)); + adjacencyList.computeIfAbsent(account.get(i), k -> new ArrayList<>()).add(firstEmail); } } - Set seen = new HashSet<>(); - List> ans = new ArrayList<>(); - for (String email : graph.keySet()) { - if (!seen.contains(email)) { - seen.add(email); + Set visited = new HashSet<>(); + List> mergedAccounts = new ArrayList<>(); + for (List account : accounts) { + String name = account.get(0); + String firstEmail = account.get(1); + if (!visited.contains(firstEmail)) { Stack stack = new Stack<>(); - stack.push(email); - List component = new ArrayList<>(); + stack.push(firstEmail); + List mergedAccount = new ArrayList<>(); + mergedAccount.add(name); while (!stack.isEmpty()) { - String node = stack.pop(); - component.add(node); - for (String neighbour : graph.get(node)) { - if (!seen.contains(neighbour)) { - seen.add(neighbour); - stack.push(neighbour); + String removedEmail = stack.pop(); + visited.add(removedEmail); + mergedAccount.add(removedEmail); + for (String neighbor : adjacencyList.getOrDefault(removedEmail, new ArrayList<>())) { + if (!visited.contains(neighbor)) { + visited.add(neighbor); + stack.push(neighbor); } } } - Collections.sort(component); - component.add(0, emailToNameMap.get(email)); - ans.add(component); + Collections.sort(mergedAccount.subList(1, mergedAccount.size())); + mergedAccounts.add(mergedAccount); } } - return ans; + return mergedAccounts; } } diff --git a/Medium/Add Bold Tag in String.java b/Medium/Add Bold Tag in String.java index bd262a02..024e1823 100644 --- a/Medium/Add Bold Tag in String.java +++ b/Medium/Add Bold Tag in String.java @@ -1,30 +1,44 @@ class Solution { - public String addBoldTag(String S, String[] dict) { - int N = S.length(); - boolean[] mask = new boolean[N]; - for (int i = 0; i < N; ++i) { - for (String word: dict) search: { - for (int k = 0; k < word.length(); ++k) { - if (k + i >= S.length() || S.charAt(k + i) != word.charAt(k)) { - break search; - } - } - for (int j = i; j < i + word.length(); ++j) { - mask[j] = true; - } + public String addBoldTag(String s, String[] words) { + List indexes = new ArrayList<>(); + for (String word : words) { + indexes.addAll(getIndexPair(s, word)); + } + Collections.sort(indexes, + Comparator.comparingInt((int[] o) -> o[0]).thenComparingInt(o -> o[1])); + Set startIdx = new HashSet<>(); + Set endIdx = new HashSet<>(); + int idx = 0; + while (idx < indexes.size()) { + int currStart = indexes.get(idx)[0]; + int currEnd = indexes.get(idx)[1]; + idx++; + while (idx < indexes.size() && indexes.get(idx)[0] <= currEnd + 1) { + currEnd = Math.max(currEnd, indexes.get(idx++)[1]); } + startIdx.add(currStart); + endIdx.add(currEnd); } - StringBuilder ans = new StringBuilder(); - int anchor = 0; - for (int i = 0; i < N; ++i) { - if (mask[i] && (i == 0 || !mask[i - 1])) { - ans.append(""); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + if (startIdx.contains(i)) { + sb.append(""); + } + sb.append(s.charAt(i)); + if (endIdx.contains(i)) { + sb.append(""); } - ans.append(S.charAt(i)); - if (mask[i] && (i == N - 1 || !mask[i + 1])) { - ans.append(""); + } + return sb.toString(); + } + + private List getIndexPair(String s, String word) { + List indexPairs = new ArrayList<>(); + for (int i = 0; i < s.length() - word.length() + 1; i++) { + if (s.startsWith(word, i)) { + indexPairs.add(new int[]{i, i + word.length() - 1}); } } - return ans.toString(); + return indexPairs; } } diff --git a/Medium/Add Minimum Number of Rungs.java b/Medium/Add Minimum Number of Rungs.java new file mode 100644 index 00000000..f473ea61 --- /dev/null +++ b/Medium/Add Minimum Number of Rungs.java @@ -0,0 +1,11 @@ +class Solution { + public int addRungs(int[] rungs, int dist) { + int numOfRungs = 0; + int currPos = 0; + for (int rung : rungs) { + numOfRungs += (rung - currPos - 1) / dist; + currPos = rung; + } + return numOfRungs; + } +} diff --git a/Medium/Add One Row to Tree.java b/Medium/Add One Row to Tree.java index 06a5e253..38075d28 100644 --- a/Medium/Add One Row to Tree.java +++ b/Medium/Add One Row to Tree.java @@ -4,40 +4,48 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public TreeNode addOneRow(TreeNode root, int v, int d) { - if (d == 1) { - TreeNode t = new TreeNode(v); - t.left = root; - return t; - } - - helper(root, v, d, 1); - return root; + public TreeNode addOneRow(TreeNode root, int val, int depth) { + if (depth == 1) { + TreeNode newRoot = new TreeNode(val); + newRoot.left = root; + return newRoot; } - - private void helper(TreeNode root, int v, int d, int currLevel) { - if (currLevel == d-1) { - TreeNode t1 = new TreeNode(v); - TreeNode t2 = new TreeNode(v); - - t1.left = root.left; - t2.right = root.right; - root.left = t1; - root.right = t2; - - return; - } - - if (root.left != null) { - helper(root.left, v, d, currLevel + 1); + int currDepth = 1; + Queue queue = new LinkedList<>(); + queue.add(root); + while (currDepth < depth - 1) { + Queue temp = new LinkedList<>(); + while (!queue.isEmpty()) { + TreeNode removed = queue.remove(); + if (removed.left != null) { + temp.add(removed.left); } - - if (root.right != null) { - helper(root.right, v, d, currLevel + 1); + if (removed.right != null) { + temp.add(removed.right); } + } + queue = temp; + currDepth++; + } + while (!queue.isEmpty()) { + TreeNode node = queue.remove(); + TreeNode temp = node.left; + node.left = new TreeNode(val); + node.left.left = temp; + temp = node.right; + node.right = new TreeNode(val); + node.right.right = temp; } + return root; + } } diff --git a/Medium/Add Two Numbers II.java b/Medium/Add Two Numbers II.java index ae9591cd..59d717cb 100644 --- a/Medium/Add Two Numbers II.java +++ b/Medium/Add Two Numbers II.java @@ -3,65 +3,46 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { - ListNode l1Rev = reverse(l1); - ListNode l2Rev = reverse(l2); - - ListNode ans = new ListNode(-1); - ListNode curr = ans; + ListNode rev1 = reverse(l1); + ListNode rev2 = reverse(l2); + ListNode dummy = new ListNode(); + ListNode curr = dummy; int carry = 0; - - while (l1Rev != null || l2Rev != null) { - int temp = 0; - if (l1Rev != null && l2Rev != null) { - temp = l1Rev.val + l2Rev.val + carry; - l1Rev = l1Rev.next; - l2Rev = l2Rev.next; + while (rev1 != null || rev2 != null || carry > 0) { + if (rev1 != null && rev2 != null) { + carry += rev1.val + rev2.val; + rev1 = rev1.next; + rev2 = rev2.next; + } else if (rev1 == null && rev2 != null) { + carry += rev2.val; + rev2 = rev2.next; + } else if (rev1 != null && rev2 == null) { + carry += rev1.val; + rev1 = rev1.next; } - else if(l1Rev != null) { - temp = l1Rev.val + carry; - l1Rev = l1Rev.next; - } - else { - temp = l2Rev.val + carry; - l2Rev = l2Rev.next; - } - - if (temp > 9) { - carry = temp/10; - temp = temp%10; - } - else { - carry = 0; - } - curr.next = new ListNode(temp); - curr = curr.next; - } - - if (carry != 0) { - curr.next = new ListNode(carry); + curr.next = new ListNode(carry % 10); curr = curr.next; + carry /= 10; } - - return reverse(ans.next); + return reverse(dummy.next); } - private ListNode reverse(ListNode head) { - ListNode curr = head; + private ListNode reverse(ListNode node) { + ListNode curr = node; ListNode prev = null; - ListNode next = null; - while (curr != null) { - next = curr.next; + ListNode next = curr.next; curr.next = prev; prev = curr; curr = next; } - return prev; } } diff --git a/Medium/Add Two Numbers.java b/Medium/Add Two Numbers.java index 4917bf04..8245945b 100644 --- a/Medium/Add Two Numbers.java +++ b/Medium/Add Two Numbers.java @@ -3,34 +3,34 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { - ListNode ans = new ListNode(-1); - ListNode curr = ans; + ListNode root = new ListNode(-1); + ListNode curr = root; int carry = 0; - while (l1 != null || l2 != null || carry > 0) { - int temp = carry; + while (l1 != null || l2 != null || carry != 0) { + int currSum = carry; if (l1 != null && l2 != null) { - temp += l1.val + l2.val; + currSum += l1.val + l2.val; l1 = l1.next; l2 = l2.next; - } - else if (l1 != null && l2 == null) { - temp += l1.val; + } else if (l1 != null && l2 == null) { + currSum += l1.val; l1 = l1.next; - } - else if (l1 == null && l2 != null) { - temp += l2.val; + } else if (l1 == null && l2 != null) { + currSum += l2.val; l2 = l2.next; } - carry = temp > 9 ? temp / 10 : 0; - temp = temp % 10; - curr.next = new ListNode(temp); + carry = currSum > 9 ? 1 : 0; + currSum %= 10; + curr.next = new ListNode(currSum); curr = curr.next; } - return ans.next; + return root.next; } } diff --git a/Medium/Add Two Polynomials Represented as Linked Lists.java b/Medium/Add Two Polynomials Represented as Linked Lists.java new file mode 100644 index 00000000..f7eafe3a --- /dev/null +++ b/Medium/Add Two Polynomials Represented as Linked Lists.java @@ -0,0 +1,43 @@ +/** + * Definition for polynomial singly-linked list. + * class PolyNode { + * int coefficient, power; + * PolyNode next = null; + + * PolyNode() {} + * PolyNode(int x, int y) { this.coefficient = x; this.power = y; } + * PolyNode(int x, int y, PolyNode next) { this.coefficient = x; this.power = y; this.next = next; } + * } + */ + +class Solution { + public PolyNode addPoly(PolyNode poly1, PolyNode poly2) { + Map powerToValue = new HashMap<>(); + populateMap(powerToValue, poly1); + populateMap(powerToValue, poly2); + List powerKeys = new ArrayList<>(powerToValue.keySet()); + Collections.sort(powerKeys); + PolyNode dummy = new PolyNode(); + PolyNode curr = dummy; + for (int i = powerKeys.size() - 1; i >= 0; i--) { + if (powerToValue.get(powerKeys.get(i)) == 0) { + continue; + } + PolyNode node = new PolyNode(powerToValue.get(powerKeys.get(i)), powerKeys.get(i)); + curr.next = node; + curr = curr.next; + } + return dummy.next; + } + + private void populateMap(Map powerToValue, PolyNode poly) { + while (poly != null) { + PolyNode node = poly; + int power = node.power; + if (node.coefficient != 0) { + powerToValue.put(power, powerToValue.getOrDefault(power, 0) + node.coefficient); + } + poly = poly.next; + } + } +} diff --git a/Medium/Add and Search Word - Data structure design.java b/Medium/Add and Search Word - Data structure design.java deleted file mode 100644 index 2d73cc43..00000000 --- a/Medium/Add and Search Word - Data structure design.java +++ /dev/null @@ -1,68 +0,0 @@ -class WordDictionary { - - /** Initialize your data structure here. */ - Node root; - public WordDictionary() { - root = new Node('-'); - } - - /** Adds a word into the data structure. */ - public void addWord(String word) { - Node curr = root; - for (char c : word.toCharArray()) { - if (curr.children[c - 'a'] == null) { - curr.children[c - 'a'] = new Node(c); - } - curr = curr.children[c - 'a']; - } - curr.isWord = true; - } - - /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ - public boolean search(String word) { - Node curr = root; - return searchHelper(curr, word, 0); - } - - private boolean searchHelper(Node curr, String word, int idx) { - if (idx == word.length()) { - return curr.isWord; - } - char c = word.charAt(idx); - if (c != '.') { - if (curr.children[c - 'a'] == null) { - return false; - } - return searchHelper(curr.children[c - 'a'], word, idx + 1); - } - else { - boolean flag = false; - for (Node child : curr.children) { - if (child != null) { - flag = flag | searchHelper(child, word, idx + 1); - } - } - return flag; - } - } -} - - -class Node { - char c; - Node[] children; - boolean isWord; - - public Node(char c) { - this.c = c; - children = new Node[26]; - isWord = false; - } -} - -/** - * Your WordDictionary object will be instantiated and called as such: - * WordDictionary obj = new WordDictionary(); - * obj.addWord(word); - * boolean param_2 = obj.search(word); - */ diff --git a/Medium/Adding Spaces to a String.java b/Medium/Adding Spaces to a String.java new file mode 100644 index 00000000..f1a0dc5f --- /dev/null +++ b/Medium/Adding Spaces to a String.java @@ -0,0 +1,12 @@ +class Solution { + public String addSpaces(String s, int[] spaces) { + StringBuilder sb = new StringBuilder(); + int startIdx = 0; + for (int spaceIdx : spaces) { + sb.append(s.substring(startIdx, spaceIdx)).append(" "); + startIdx = spaceIdx; + } + sb.append(s.substring(startIdx)); + return sb.toString(); + } +} diff --git a/Medium/Adding Two Negabinary Numbers.java b/Medium/Adding Two Negabinary Numbers.java new file mode 100644 index 00000000..7f371f30 --- /dev/null +++ b/Medium/Adding Two Negabinary Numbers.java @@ -0,0 +1,23 @@ +class Solution { + public int[] addNegabinary(int[] arr1, int[] arr2) { + int idxOne = arr1.length - 1; + int idxTwo = arr2.length - 1; + int carry = 0; + Stack stack = new Stack<>(); + while (idxOne >= 0 || idxTwo >= 0 || carry != 0) { + int valOne = idxOne >= 0 ? arr1[idxOne--] : 0; + int valTwo = idxTwo >= 0 ? arr2[idxTwo--] : 0; + carry = valOne + valTwo + carry; + stack.push(carry & 1); + carry = -(carry >> 1); + } + while (!stack.isEmpty() && stack.peek() == 0) { + stack.pop(); + } + int[] result = new int[stack.size()]; + for (int i = 0; i < result.length; i++) { + result[i] = stack.pop(); + } + return result.length == 0 ? new int[]{0} : result; + } +} diff --git a/Medium/Advantage Shuffle.java b/Medium/Advantage Shuffle.java new file mode 100644 index 00000000..2bb3ba9b --- /dev/null +++ b/Medium/Advantage Shuffle.java @@ -0,0 +1,31 @@ +class Solution { + public int[] advantageCount(int[] A, int[] B) { + TreeMap map = new TreeMap<>(); + for (int num : A) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + int[] result = new int[A.length]; + Arrays.fill(result, Integer.MIN_VALUE); + List indexesNotPopulated = new ArrayList<>(); + for (int i = 0; i < B.length; i++) { + Integer upper = map.higherKey(B[i]); + if (upper != null) { + result[i] = upper; + map.put(upper, map.get(upper) - 1); + if (map.get(upper) == 0) { + map.remove(upper); + } + } else { + indexesNotPopulated.add(i); + } + } + Iterator iterator = indexesNotPopulated.iterator(); + for (Integer key : map.keySet()) { + int value = map.get(key); + while (value-- > 0) { + result[iterator.next()] = key; + } + } + return result; + } +} diff --git a/Medium/All Ancestors of a Node in a Directed Acyclic Graph.java b/Medium/All Ancestors of a Node in a Directed Acyclic Graph.java new file mode 100644 index 00000000..36063815 --- /dev/null +++ b/Medium/All Ancestors of a Node in a Directed Acyclic Graph.java @@ -0,0 +1,36 @@ +class Solution { + public List> getAncestors(int n, int[][] edges) { + Map> graph = new HashMap<>(); + int[] indegree = new int[n]; + for (int[] edge : edges) { + graph.computeIfAbsent(edge[0], k -> new ArrayList<>()).add(edge[1]); + indegree[edge[1]]++; + } + Queue queue = new LinkedList<>(); + Map> ancestors = new HashMap<>(); + for (int i = 0; i < n; i++) { + if (indegree[i] == 0) { + queue.offer(i); + } + } + while (!queue.isEmpty()) { + int node = queue.poll(); + ancestors.computeIfAbsent(node, k -> new HashSet<>()); + for (int dependents : graph.getOrDefault(node, Collections.emptyList())) { + ancestors.computeIfAbsent(dependents, k -> new HashSet<>()).add(node); + ancestors.get(dependents).addAll(ancestors.get(node)); + indegree[dependents]--; + if (indegree[dependents] == 0) { + queue.offer(dependents); + } + } + } + List> result = new ArrayList<>(); + for (int i = 0; i < n; i++) { + List currNodeAncestors = new ArrayList<>(ancestors.getOrDefault(i, Collections.emptySet())); + currNodeAncestors.sort(Comparator.naturalOrder()); + result.add(currNodeAncestors); + } + return result; + } +} diff --git a/Medium/All Divisions With the Highest Score of a Binary Array.java b/Medium/All Divisions With the Highest Score of a Binary Array.java new file mode 100644 index 00000000..f47caba5 --- /dev/null +++ b/Medium/All Divisions With the Highest Score of a Binary Array.java @@ -0,0 +1,25 @@ +class Solution { + public List maxScoreIndices(int[] nums) { + int n = nums.length; + int[] prefix = new int[n + 1]; + for (int i = 0; i < n; i++) { + prefix[i + 1] = nums[i] + prefix[i]; + } + int maxScore = 0; + Map map = new HashMap<>(); + for (int i = 0; i < n + 1; i++) { + int onesToRight = prefix[n] - prefix[i]; + int zerosToLeft = i - prefix[i]; + int currScore = zerosToLeft + onesToRight; + maxScore = Math.max(maxScore, currScore); + map.put(i, currScore); + } + List result = new ArrayList<>(); + for (Integer key : map.keySet()) { + if (map.get(key).equals(maxScore)) { + result.add(key); + } + } + return result; + } +} diff --git a/Medium/All Elements in Two Binary Search Trees.java b/Medium/All Elements in Two Binary Search Trees.java index a973fd93..92fc3d9f 100644 --- a/Medium/All Elements in Two Binary Search Trees.java +++ b/Medium/All Elements in Two Binary Search Trees.java @@ -15,33 +15,36 @@ */ class Solution { public List getAllElements(TreeNode root1, TreeNode root2) { - Stack stack1 = new Stack<>(); - Stack stack2 = new Stack<>(); - updateStack(stack1, root1); - updateStack(stack2, root2); + Stack stackOne = new Stack<>(); + Stack stackTwo = new Stack<>(); + while (root1 != null) { + stackOne.push(root1); + root1 = root1.left; + } + while (root2 != null) { + stackTwo.push(root2); + root2 = root2.left; + } List list = new ArrayList<>(); - while (!stack1.isEmpty() || !stack2.isEmpty()) { - if (!stack1.isEmpty() && !stack2.isEmpty()) { - if (stack1.peek().val < stack2.peek().val) { - TreeNode popped = stack1.pop(); + while (!stackOne.isEmpty() || !stackTwo.isEmpty()) { + if (!stackOne.isEmpty() && !stackTwo.isEmpty()) { + if (stackOne.peek().val < stackTwo.peek().val) { + TreeNode popped = stackOne.pop(); list.add(popped.val); - updateStack(stack1, popped.right); - } - else { - TreeNode popped = stack2.pop(); + updateStack(stackOne, popped.right); + } else { + TreeNode popped = stackTwo.pop(); list.add(popped.val); - updateStack(stack2, popped.right); + updateStack(stackTwo, popped.right); } - } - else if (!stack1.isEmpty() && stack2.isEmpty()) { - TreeNode popped = stack1.pop(); + } else if (!stackOne.isEmpty() && stackTwo.isEmpty()) { + TreeNode popped = stackOne.pop(); list.add(popped.val); - updateStack(stack1, popped.right); - } - else { - TreeNode popped = stack2.pop(); + updateStack(stackOne, popped.right); + } else { + TreeNode popped = stackTwo.pop(); list.add(popped.val); - updateStack(stack2, popped.right); + updateStack(stackTwo, popped.right); } } return list; diff --git a/Medium/All Nodes Distance K in Binary Tree.java b/Medium/All Nodes Distance K in Binary Tree.java index 4c2ac67d..9f88451e 100644 --- a/Medium/All Nodes Distance K in Binary Tree.java +++ b/Medium/All Nodes Distance K in Binary Tree.java @@ -8,61 +8,48 @@ * } */ class Solution { - List list; - TreeNode target; - int K; - public List distanceK(TreeNode root, TreeNode target, int K) { - list = new ArrayList<>(); - this.target = target; - this.K = K; - dfs(root); - return list; - } - - private int dfs(TreeNode node) { - if (node == null) { - return -1; + public List distanceK(TreeNode root, TreeNode target, int k) { + List result = new ArrayList<>(); + dfs(root, target, k, result); + return result; } - else if (node == target) { - subtreeDfs(node, 0); - return 1; - } - else { - int L = dfs(node.left); - int R = -1; - if (L != -1) { - if (L == K) { - list.add(node.val); + + private int dfs(TreeNode node, TreeNode target, int k, List result) { + if (node == null) { + return -1; + } + if (node == target) { + dfs(node, 0, k, result); + return 1; } - subtreeDfs(node.right, L + 1); - return L + 1; - } - else if ((R = dfs(node.right)) != -1) { - if (R == K) { - list.add(node.val); + int left = dfs(node.left, target, k, result); + if (left != -1) { + if (left == k) { + result.add(node.val); + } + dfs(node.right, left + 1, k, result); + return left + 1; + } + int right = dfs(node.right, target, k, result); + if (right != -1) { + if (right == k) { + result.add(node.val); + } + dfs(node.left, right + 1, k, result); + return right + 1; } - subtreeDfs(node.left, R + 1); - return R + 1; - } - else { return -1; - } - } - } - - private void subtreeDfs(TreeNode node, int dist) { - if (node == null) { - return; } - if (dist == K) { - list.add(node.val); - } - else if (dist > K) { - return; - } - else { - subtreeDfs(node.left, dist + 1); - subtreeDfs(node.right, dist + 1); + + private void dfs(TreeNode node, int distance, int k, List result) { + if (node == null || distance > k) { + return; + } + if (distance == k) { + result.add(node.val); + return; + } + dfs(node.left, distance + 1, k, result); + dfs(node.right, distance + 1, k, result); } - } } diff --git a/Medium/All Possible Full Binary Trees.java b/Medium/All Possible Full Binary Trees.java index 7c7853c4..868b8271 100644 --- a/Medium/All Possible Full Binary Trees.java +++ b/Medium/All Possible Full Binary Trees.java @@ -4,40 +4,42 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public List allPossibleFBT(int N) { - List ans = new LinkedList<>(); - if (N % 2 == 0) { - return ans; - } - - return helper(N); + public List allPossibleFBT(int n) { + Map> dp = new HashMap<>(); + return allPossibleFBTHelper(n, dp); + } + + private List allPossibleFBTHelper(int n, Map> dp) { + if (dp.containsKey(n)) { + return dp.get(n); } - - private List helper(int N) { - List ans = new LinkedList<>(); - if (N == 1) { - ans.add(new TreeNode(0)); - return ans; - } - - for (int i = 1; i <= N - 2; i += 2) { - List left = helper(i); - List right = helper(N - i - 1); - - for (TreeNode leftNode : left) { - for (TreeNode rightNode : right) { - TreeNode node = new TreeNode(0); - node.left = leftNode; - node.right = rightNode; - ans.add(node); - } - } + List result = new ArrayList<>(); + if (n == 1) { + result.add(new TreeNode(0)); + } else if (n % 2 == 1) { + for (int i = 0; i < n; i++) { + int j = n - 1 - i; + for (TreeNode left : allPossibleFBTHelper(i, dp)) { + for (TreeNode right : allPossibleFBTHelper(j, dp)) { + TreeNode root = new TreeNode(0); + root.left = left; + root.right = right; + result.add(root); + } } - - return ans; + } } + dp.put(n, result); + return dp.get(n); + } } diff --git a/Medium/Amount of Time for Binary Tree to Be Infected.java b/Medium/Amount of Time for Binary Tree to Be Infected.java new file mode 100644 index 00000000..8d5540ab --- /dev/null +++ b/Medium/Amount of Time for Binary Tree to Be Infected.java @@ -0,0 +1,65 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public int amountOfTime(TreeNode root, int start) { + Map nodeToParent = new HashMap<>(); + buildNodeToParentRelationship(root, null, nodeToParent); + TreeNode startNode = nodeToParent.keySet() + .stream() + .filter(node -> node.val == start) + .findFirst() + .orElse(null); + return calculateInfectionTime(nodeToParent, startNode); + } + + private void buildNodeToParentRelationship(TreeNode root, TreeNode parent, Map nodeToParent) { + if (root == null) { + return; + } + nodeToParent.put(root, parent); + buildNodeToParentRelationship(root.left, root, nodeToParent); + buildNodeToParentRelationship(root.right, root, nodeToParent); + } + + private int calculateInfectionTime(Map nodeToParent, TreeNode startNode) { + int time = 0; + Set isInfected = new HashSet<>(); + Queue queue = new LinkedList<>(); + queue.add(startNode); + isInfected.add(startNode.val); + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + TreeNode removed = queue.remove(); + TreeNode parent = nodeToParent.get(removed); + if (nodeToParent.get(removed) != null && isInfected.add(nodeToParent.get(removed).val)) { + queue.add(nodeToParent.get(removed)); + } + if (removed.left != null && isInfected.add(removed.left.val)) { + queue.add(removed.left); + } + if (removed.right != null && isInfected.add(removed.right.val)) { + queue.add(removed.right); + } + } + if (queue.isEmpty()) { + break; + } + time++; + } + return time; + } +} diff --git a/Medium/Analyze User Website Visit Pattern.java b/Medium/Analyze User Website Visit Pattern.java index def6a086..1fbb2fc3 100644 --- a/Medium/Analyze User Website Visit Pattern.java +++ b/Medium/Analyze User Website Visit Pattern.java @@ -1,62 +1,41 @@ class Solution { public List mostVisitedPattern(String[] username, int[] timestamp, String[] website) { - Map> map = new HashMap<>(); - for (int i = 0; i < timestamp.length; i++) { - map.computeIfAbsent(username[i], k -> new ArrayList<>()).add( - new WebEntry(website[i], timestamp[i], username[i]) - ); + Map> userToVisitMapping = new HashMap<>(); + for (int i = 0; i < username.length; i++) { + userToVisitMapping.computeIfAbsent(username[i], k -> new ArrayList<>()).add(i); } - Map> visitMap = new HashMap<>(); - Set threeSequenceSet = new HashSet<>(); - for (String key : map.keySet()) { - List webentries = map.get(key); - Collections.sort(webentries, new Comparator(){ - public int compare(WebEntry w1, WebEntry w2) { - return w1.timestamp - w2.timestamp; - } - }); - for (int i = 0; i < webentries.size(); i++) { - for (int j = i + 1; j < webentries.size(); j++) { - for (int k = j + 1; k < webentries.size(); k++) { - String websiteKey = ( - webentries.get(i).website + " " + - webentries.get(j).website + " " + - webentries.get(k).website - ); - visitMap.computeIfAbsent(websiteKey, m -> new HashSet<>()).add(key); - threeSequenceSet.add(websiteKey); + Map> patternToUserMapping = new HashMap<>(); + int maxCount = 0; + String resultingPattern = null; + for (String key : userToVisitMapping.keySet()) { + List visitedWebsiteInOrder = + userToVisitMapping.get(key).stream() + .sorted(Comparator.comparingInt(a -> timestamp[a])) + .map(i -> website[i]) + .collect(Collectors.toList()); + for (int i = 0; i < visitedWebsiteInOrder.size() - 2; i++) { + for (int j = i + 1; j < visitedWebsiteInOrder.size() - 1; j++) { + for (int k = j + 1; k < visitedWebsiteInOrder.size(); k++) { + String pattern = + visitedWebsiteInOrder.get(i) + + " " + + visitedWebsiteInOrder.get(j) + + " " + + visitedWebsiteInOrder.get(k); + patternToUserMapping.computeIfAbsent(pattern, l -> new HashSet<>()).add(key); + if (maxCount <= patternToUserMapping.get(pattern).size()) { + if (maxCount < patternToUserMapping.get(pattern).size()) { + resultingPattern = pattern; + maxCount = patternToUserMapping.get(pattern).size(); + } else if (pattern.compareTo(resultingPattern) < 0) { + resultingPattern = pattern; + } + } + maxCount = Math.max(maxCount, patternToUserMapping.get(pattern).size()); } } } } - List threeSequenceList = new ArrayList<>(threeSequenceSet); - Collections.sort(threeSequenceList, new Comparator(){ - public int compare(String s1, String s2) { - int c = visitMap.get(s2).size() - visitMap.get(s1).size(); - if (c != 0) { - return c; - } - return s1.compareTo(s2); - } - }); - String[] ansArr = threeSequenceList.get(0).split("\\s+"); - List ans = new ArrayList<>(); - for (int i = 0; i < ansArr.length; i++) { - ans.add(ansArr[i]); - } - return ans; - } -} - - -class WebEntry { - String website; - int timestamp; - String username; - - public WebEntry(String website, int timestamp, String username) { - this.website = website; - this.timestamp = timestamp; - this.username = username; + return Arrays.stream(resultingPattern.split("\\s+")).collect(Collectors.toList()); } } diff --git a/Medium/Append Characters to String to Make Subsequence.java b/Medium/Append Characters to String to Make Subsequence.java new file mode 100644 index 00000000..af35ca3d --- /dev/null +++ b/Medium/Append Characters to String to Make Subsequence.java @@ -0,0 +1,13 @@ +class Solution { + public int appendCharacters(String s, String t) { + int idxS = 0; + int idxT = 0; + while (idxS < s.length() && idxT < t.length()) { + if (s.charAt(idxS) == t.charAt(idxT)) { + idxT++; + } + idxS++; + } + return idxT == t.length() ? 0 : t.length() - idxT; + } +} diff --git a/Medium/Append K Integers With Minimal Sum.java b/Medium/Append K Integers With Minimal Sum.java new file mode 100644 index 00000000..bea57e93 --- /dev/null +++ b/Medium/Append K Integers With Minimal Sum.java @@ -0,0 +1,20 @@ +class Solution { + public long minimalKSum(int[] nums, int k) { + Arrays.sort(nums); + long sum = 0; + long low = 1; + for (int num : nums) { + if (num > low) { + long high = Math.min(num - 1, low + k - 1); + int count = (int) (high - low + 1); + sum += (low + high) * count / 2; + k -= count; + if (k == 0) { + return sum; + } + } + low = num + 1; + } + return sum + (2 * low + k - 1) * k / 2; + } +} diff --git a/Medium/Apply Discount to Prices.java b/Medium/Apply Discount to Prices.java new file mode 100644 index 00000000..6c3974c9 --- /dev/null +++ b/Medium/Apply Discount to Prices.java @@ -0,0 +1,48 @@ +class Solution { + public String discountPrices(String sentence, int discount) { + StringBuilder sb = new StringBuilder(); + int idx = 0; + int n = sentence.length(); + while (idx < n) { + if (sentence.charAt(idx) == '$') { + if (idx == 0 || sentence.charAt(idx - 1) == ' ') { + sb.append(sentence.charAt(idx++)); + StringBuilder possibleDigit = new StringBuilder(); + boolean isDigit = true; + while (idx < n && sentence.charAt(idx) != ' ') { + if (!Character.isDigit(sentence.charAt(idx))) { + isDigit = false; + } + possibleDigit.append(sentence.charAt(idx++)); + } + if (possibleDigit.length() == 0) { + continue; + } + if (isDigit) { + long price = Long.parseLong(possibleDigit.toString()); + long updatedPrice = price * (100 - discount); + sb.append(getFormattedPrice(updatedPrice)); + } else { + sb.append(possibleDigit); + } + } else { + sb.append(sentence.charAt(idx++)); + } + } else { + sb.append(sentence.charAt(idx++)); + } + } + return sb.toString(); + } + + private String getFormattedPrice(long price) { + if (price < 10) { + return "0.0" + price; + } else if (price < 100) { + return "0." + price; + } else { + String priceString = String.valueOf(price); + return priceString.substring(0, priceString.length() - 2) + "." + priceString.substring(priceString.length() - 2); + } + } +} diff --git a/Medium/Apply Operations to Make String Empty.java b/Medium/Apply Operations to Make String Empty.java new file mode 100644 index 00000000..c378a060 --- /dev/null +++ b/Medium/Apply Operations to Make String Empty.java @@ -0,0 +1,18 @@ +class Solution { + public String lastNonEmptyString(String s) { + Map map = new HashMap<>(); + int maxFrequency = 0; + for (int i = 0; i < s.length(); i++) { + map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1); + maxFrequency = Math.max(maxFrequency, map.get(s.charAt(i))); + } + StringBuilder result = new StringBuilder(); + for (int i = s.length() - 1; i >= 0; i--) { + if (map.get(s.charAt(i)) == maxFrequency) { + result.append(s.charAt(i)); + map.put(s.charAt(i), map.get(s.charAt(i)) - 1); + } + } + return result.reverse().toString(); + } +} diff --git a/Medium/Arithmetic Slices.java b/Medium/Arithmetic Slices.java index 67a68778..0b620a90 100644 --- a/Medium/Arithmetic Slices.java +++ b/Medium/Arithmetic Slices.java @@ -1,15 +1,11 @@ class Solution { - public int numberOfArithmeticSlices(int[] A) { + public int numberOfArithmeticSlices(int[] nums) { + int[] dp = new int[nums.length]; int count = 0; - for (int i = 0; i < A.length - 2; i++) { - int diff = A[i + 1] - A[i]; - for (int j = i + 2; j < A.length; j++) { - if (A[j] - A[j - 1] == diff) { - count++; - } - else { - break; - } + for (int i = 2; i < dp.length; i++) { + if (nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]) { + dp[i] = dp[i - 1] + 1; + count += dp[i]; } } return count; diff --git a/Medium/Arithmetic Subarrays.java b/Medium/Arithmetic Subarrays.java new file mode 100644 index 00000000..ae79bb2a --- /dev/null +++ b/Medium/Arithmetic Subarrays.java @@ -0,0 +1,24 @@ +class Solution { + public List checkArithmeticSubarrays(int[] nums, int[] l, int[] r) { + List queryResult = new ArrayList<>(); + for (int idx = 0; idx < l.length; idx++) { + queryResult.add(isArithmeticProgressionPossible(nums, l[idx], r[idx])); + } + return queryResult; + } + + private boolean isArithmeticProgressionPossible(int[] nums, int startIdx, int endIdx) { + List sequence = new ArrayList<>(); + for (int idx = startIdx; idx <= endIdx; idx++) { + sequence.add(nums[idx]); + } + Collections.sort(sequence); + Integer diff = sequence.get(1) - sequence.get(0); + for (int idx = 2; idx < sequence.size(); idx++) { + if (diff != (sequence.get(idx) - sequence.get(idx - 1))) { + return false; + } + } + return true; + } +} diff --git a/Medium/As Far from Land as Possible.java b/Medium/As Far from Land as Possible.java index 2096777d..6e1ba29a 100644 --- a/Medium/As Far from Land as Possible.java +++ b/Medium/As Far from Land as Possible.java @@ -1,36 +1,38 @@ class Solution { + + private static final int[][] DIRS = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; + public int maxDistance(int[][] grid) { - if (grid.length == 0 || grid[0].length == 0) { - return -1; - } - int[][] dirs = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; - boolean[][] visited = new boolean[grid.length][grid[0].length]; - Queue queue = new LinkedList<>(); - for (int i = 0; i < grid.length; i++) { - for (int j = 0; j < grid[0].length; j++) { + int rows = grid.length; + int cols = grid[0].length; + Queue queue = new LinkedList<>(); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { if (grid[i][j] == 1) { queue.add(new int[]{i, j}); - visited[i][j] = true; } } } - int maxDist = -1; + if (queue.isEmpty() || queue.size() == rows * cols) { + return -1; + } + int distance = 0; while (!queue.isEmpty()) { int size = queue.size(); while (size-- > 0) { - int[] curr = queue.remove(); - for (int[] dir : dirs) { - int x = curr[0] + dir[0]; - int y = curr[1] + dir[1]; - if (x >= 0 && x < grid.length && y >= 0 && y < grid[0].length && !visited[x][y] && grid[x][y] == 0) { - visited[x][y] = true; - queue.add(new int[]{x, y}); + int[] removed = queue.remove(); + for (int[] dir : DIRS) { + int x = removed[0] + dir[0]; + int y = removed[1] + dir[1]; + if (x < 0 || y < 0 || x >= rows || y >= cols || grid[x][y] == 1) { + continue; } + grid[x][y] = 1; + queue.add(new int[]{x, y}); } } - maxDist++; + distance++; } - - return maxDist == 0 ? -1 : maxDist; + return distance - 1; } } diff --git a/Medium/Asteroid Collision.java b/Medium/Asteroid Collision.java index dc8ca9bf..64a10bf3 100644 --- a/Medium/Asteroid Collision.java +++ b/Medium/Asteroid Collision.java @@ -1,29 +1,33 @@ class Solution { - public int[] asteroidCollision(int[] asteroids) { - Stack stack = new Stack<>(); - for (int asteroid : asteroids) { - boolean toAdd = true; - if (asteroid < 0) { - while (!stack.isEmpty() && stack.peek() > 0) { - if (Math.abs(asteroid) > stack.peek()) { - stack.pop(); - continue; - } - else if (Math.abs(asteroid) == stack.peek()) { - stack.pop(); - } - toAdd = false; - break; + public int[] asteroidCollision(int[] asteroids) { + List result = new ArrayList<>(); + int idx = 0; + while (idx < asteroids.length && asteroids[idx] < 0) { + result.add(asteroids[idx++]); } - } - if (toAdd) { - stack.push(asteroid); - } - } - int[] ans = new int[stack.size()]; - for (int i = ans.length - 1; i >= 0; i--) { - ans[i] = stack.pop(); + while (idx < asteroids.length) { + if (asteroids[idx] > 0) { + result.add(asteroids[idx++]); + } else { + if (result.isEmpty() || result.get(result.size() - 1) < 0) { + result.add(asteroids[idx]); + } else { + while (!result.isEmpty() && + result.get(result.size() - 1) > 0 && + result.get(result.size() - 1) < Math.abs(asteroids[idx])) { + result.remove(result.size() - 1); + } + if (!result.isEmpty() && result.get(result.size() - 1) > 0) { + if (result.get(result.size() - 1) == Math.abs(asteroids[idx])) { + result.remove(result.size() - 1); + } + } else { + result.add(asteroids[idx]); + } + } + idx++; + } + } + return result.stream().mapToInt(Integer::valueOf).toArray(); } - return ans; - } } diff --git a/Medium/Average Waiting Time.java b/Medium/Average Waiting Time.java new file mode 100644 index 00000000..afba5388 --- /dev/null +++ b/Medium/Average Waiting Time.java @@ -0,0 +1,20 @@ +class Solution { + public double averageWaitingTime(int[][] customers) { + double totalWaitingTime = 0.0; + int lastFreeTime = 0; + for (int[] customer : customers) { + int arrivalTime = customer[0]; + // Wait time before chef finishes previous task + if (lastFreeTime > arrivalTime) { + totalWaitingTime += lastFreeTime - arrivalTime; + } else { + lastFreeTime = arrivalTime; + } + // Wait time to finish task for current customer + int taskTime = customer[1]; + totalWaitingTime += taskTime; + lastFreeTime += taskTime; + } + return totalWaitingTime / customers.length; + } +} diff --git a/Medium/Bag of Tokens.java b/Medium/Bag of Tokens.java new file mode 100644 index 00000000..1a409e0c --- /dev/null +++ b/Medium/Bag of Tokens.java @@ -0,0 +1,23 @@ +class Solution { + public int bagOfTokensScore(int[] tokens, int power) { + int score = 0; + int currScore = 0; + Arrays.sort(tokens); + int left = 0; + int right = tokens.length - 1; + while (left <= right) { + if (power >= tokens[left]) { + currScore++; + power -= tokens[left++]; + } else { + if (currScore == 0) { + break; + } + currScore--; + power += tokens[right--]; + } + score = Math.max(score, currScore); + } + return score; + } +} diff --git a/Medium/Balance a Binary Search Tree.java b/Medium/Balance a Binary Search Tree.java new file mode 100644 index 00000000..dd07996e --- /dev/null +++ b/Medium/Balance a Binary Search Tree.java @@ -0,0 +1,50 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public TreeNode balanceBST(TreeNode root) { + List inorder = getInorderNodes(root); + return createBST(inorder, 0, inorder.size() - 1); + } + + private List getInorderNodes(TreeNode root) { + Stack stack = new Stack<>(); + while (root != null) { + stack.push(root); + root = root.left; + } + List list = new ArrayList<>(); + while (!stack.isEmpty()) { + TreeNode node = stack.pop(); + list.add(node.val); + TreeNode rightNode = node.right; + while (rightNode != null) { + stack.push(rightNode); + rightNode = rightNode.left; + } + } + return list; + } + + private TreeNode createBST(List list, int start, int end) { + if (start > end) { + return null; + } + int mid = (start + end) / 2; + TreeNode leftTree = createBST(list, start, mid - 1); + TreeNode rightTree = createBST(list, mid + 1, end); + return new TreeNode(list.get(mid), leftTree, rightTree); + } +} diff --git a/Medium/Basic Calculator II.java b/Medium/Basic Calculator II.java index da6ae5e4..dd97e966 100644 --- a/Medium/Basic Calculator II.java +++ b/Medium/Basic Calculator II.java @@ -1,34 +1,28 @@ class Solution { public int calculate(String s) { - Stack stack = new Stack<>(); - int num = 0; - char sign = '+'; + int currNum = 0; + int prevNum = 0; + int result = 0; + char operation = '+'; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (Character.isDigit(c)) { - num = num * 10 + Character.getNumericValue(c); - } - if (!Character.isDigit(c) && c != ' ' || i == s.length() - 1) { - if (sign == '-') { - stack.push(-num); - } - else if (sign == '+') { - stack.push(num); - } - else if (sign == '*') { - stack.push(stack.pop() * num); + currNum = currNum * 10 + Character.getNumericValue(c); + } + if ((!Character.isDigit(c) && !Character.isWhitespace(c)) || i == s.length() - 1) { + if (operation == '-' || operation == '+') { + result += prevNum; + prevNum = operation == '+' ? currNum : -currNum; + } else if (operation == '*') { + prevNum = prevNum * currNum; + } else { + prevNum = prevNum / currNum; } - else { - stack.push(stack.pop() / num); - } - sign = c; - num = 0; + operation = c; + currNum = 0; } } - int res = 0; - while (!stack.isEmpty()) { - res += stack.pop(); - } - return res; + result += prevNum; + return result; } } diff --git a/Medium/Battleships in a board.java b/Medium/Battleships in a board.java index 37d19242..d84273bc 100644 --- a/Medium/Battleships in a board.java +++ b/Medium/Battleships in a board.java @@ -1,20 +1,17 @@ class Solution { - public int countBattleships(char[][] board) { - int n = board.length; - if (n == 0) return 0; - int m = board[0].length; - - int count = 0; - for (int i=0;i 0 && board[i-1][j] == 'X')continue; - if (j > 0 && board[i][j-1] == 'X')continue; - - count++; - } + + public int countBattleships(char[][] board) { + int count = 0; + int rows = board.length; + int cols = board[0].length; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (board[i][j] == '.' || (i > 0 && board[i - 1][j] == 'X') || (j > 0 && board[i][j - 1] == 'X')) { + continue; } - - return count; + count++; + } } + return count; + } } diff --git a/Medium/Best Time to Buy and Sell Stock II.java b/Medium/Best Time to Buy and Sell Stock II.java new file mode 100644 index 00000000..675762b3 --- /dev/null +++ b/Medium/Best Time to Buy and Sell Stock II.java @@ -0,0 +1,15 @@ +class Solution { + public int maxProfit(int[] prices) { + int stockBuyPrice = Integer.MAX_VALUE; + int profit = 0; + for (int i = 0; i < prices.length; i++) { + if (prices[i] > stockBuyPrice) { + profit += prices[i] - stockBuyPrice; + stockBuyPrice = prices[i]; + } else { + stockBuyPrice = prices[i]; + } + } + return profit; + } +} diff --git a/Medium/Best Time to Buy and Sell Stock with Transaction Fee.java b/Medium/Best Time to Buy and Sell Stock with Transaction Fee.java new file mode 100644 index 00000000..1251e8d0 --- /dev/null +++ b/Medium/Best Time to Buy and Sell Stock with Transaction Fee.java @@ -0,0 +1,13 @@ +class Solution { + public int maxProfit(int[] prices, int fee) { + int n = prices.length; + int[] notHolding = new int[n]; + int[] holding = new int[n]; + holding[0] = -prices[0]; + for (int i = 1; i < n; i++) { + holding[i] = Math.max(holding[i - 1], notHolding[i - 1] - prices[i]); + notHolding[i] = Math.max(notHolding[i - 1], holding[i - 1] + prices[i] - fee); + } + return notHolding[n - 1]; + } +} diff --git a/Medium/Binary Search Tree Iterator II.java b/Medium/Binary Search Tree Iterator II.java new file mode 100644 index 00000000..61ab1d10 --- /dev/null +++ b/Medium/Binary Search Tree Iterator II.java @@ -0,0 +1,67 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class BSTIterator { + + private final Deque primary; + private final List secondary; + private int index; + + public BSTIterator(TreeNode root) { + this.primary = new ArrayDeque<>(); + this.secondary = new ArrayList<>(); + this.index = -1; + traverse(root); + } + + public boolean hasNext() { + return !primary.isEmpty() || index < secondary.size() - 1; + } + + public int next() { + index++; + if (index == secondary.size()) { + TreeNode curr = primary.pop(); + secondary.add(curr.val); + traverse(curr.right); + } + return secondary.get(index); + } + + public boolean hasPrev() { + return index > 0; + } + + public int prev() { + index--; + return secondary.get(index); + } + + private void traverse(TreeNode root) { + while (root != null) { + primary.push(root); + root = root.left; + } + } +} + +/** + * Your BSTIterator object will be instantiated and called as such: + * BSTIterator obj = new BSTIterator(root); + * boolean param_1 = obj.hasNext(); + * int param_2 = obj.next(); + * boolean param_3 = obj.hasPrev(); + * int param_4 = obj.prev(); + */ diff --git a/Medium/Binary Search Tree Iterator.java b/Medium/Binary Search Tree Iterator.java index 038f4a37..01b26971 100644 --- a/Medium/Binary Search Tree Iterator.java +++ b/Medium/Binary Search Tree Iterator.java @@ -14,34 +14,29 @@ * } */ class BSTIterator { - Stack stack; - public BSTIterator(TreeNode root) { - stack = new Stack<>(); - update(root); - } - private void update(TreeNode node) { - if (node == null) { - return; - } - stack.add(node); - TreeNode leftNode = node.left; - while (leftNode != null) { - stack.add(leftNode); - leftNode = leftNode.left; - } + private Stack stack; + + public BSTIterator(TreeNode root) { + this.stack = new Stack<>(); + updateStack(root); } - /** @return the next smallest number */ public int next() { - TreeNode node = stack.pop(); - update(node.right); + TreeNode node = this.stack.pop(); + updateStack(node.right); return node.val; } - /** @return whether we have a next smallest number */ public boolean hasNext() { - return !stack.isEmpty(); + return !this.stack.isEmpty(); + } + + private void updateStack(TreeNode node) { + while (node != null) { + this.stack.push(node); + node = node.left; + } } } diff --git a/Medium/Binary Search Tree to Greater Sum Tree.java b/Medium/Binary Search Tree to Greater Sum Tree.java index 91c63aa7..912e0699 100644 --- a/Medium/Binary Search Tree to Greater Sum Tree.java +++ b/Medium/Binary Search Tree to Greater Sum Tree.java @@ -4,32 +4,30 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { public TreeNode bstToGst(TreeNode root) { - if (root == null) { - return null; - } - TreeNode curr = root; - Stack stack = new Stack<>(); int sum = 0; - pushRight(stack, curr); - while (!stack.isEmpty()) { - TreeNode removed = stack.pop(); - sum += removed.val; - removed.val = sum; - TreeNode leftNode = removed.left; - pushRight(stack, leftNode); + TreeNode node = root; + Stack stack = new Stack<>(); + while (!stack.isEmpty() || node != null) { + while (node != null) { + stack.add(node); + node = node.right; + } + node = stack.pop(); + sum += node.val; + node.val = sum; + node = node.left; } return root; } - - private void pushRight(Stack stack, TreeNode curr) { - while (curr != null) { - stack.push(curr); - curr = curr.right; - } - } } diff --git a/Medium/Binary Tree Inorder Traversal.java b/Medium/Binary Tree Inorder Traversal.java deleted file mode 100644 index aad98c4b..00000000 --- a/Medium/Binary Tree Inorder Traversal.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode() {} - * TreeNode(int val) { this.val = val; } - * TreeNode(int val, TreeNode left, TreeNode right) { - * this.val = val; - * this.left = left; - * this.right = right; - * } - * } - */ -class Solution { - public List inorderTraversal(TreeNode root) { - List list = new ArrayList<>(); - if (root == null) { - return list; - } - Stack stack = new Stack<>(); - stack.push(root); - root = root.left; - while (root != null) { - stack.push(root); - root = root.left; - } - while (!stack.isEmpty()) { - TreeNode removed = stack.pop(); - list.add(removed.val); - removed = removed.right; - while (removed != null) { - stack.push(removed); - removed = removed.left; - } - } - return list; - } -} diff --git a/Medium/Binary Tree Level Order Traversal.java b/Medium/Binary Tree Level Order Traversal.java new file mode 100644 index 00000000..84664d71 --- /dev/null +++ b/Medium/Binary Tree Level Order Traversal.java @@ -0,0 +1,41 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public List> levelOrder(TreeNode root) { + if (root == null) { + return new ArrayList<>(); + } + Queue queue = new LinkedList<>(); + List> result = new ArrayList<>(); + queue.add(root); + while (!queue.isEmpty()) { + int size = queue.size(); + List currLevel = new ArrayList<>(); + while (size-- > 0) { + TreeNode removed = queue.remove(); + currLevel.add(removed.val); + if (removed.left != null) { + queue.add(removed.left); + } + if (removed.right != null) { + queue.add(removed.right); + } + } + result.add(currLevel); + } + return result; + } +} diff --git a/Medium/Binary Tree Longest Consecutive Sequence II.java b/Medium/Binary Tree Longest Consecutive Sequence II.java index db766780..41e04cba 100644 --- a/Medium/Binary Tree Longest Consecutive Sequence II.java +++ b/Medium/Binary Tree Longest Consecutive Sequence II.java @@ -4,46 +4,45 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public int longestConsecutive(TreeNode root) { - int[] ans = new int[1]; - helper(root, ans); - return ans[0]; + public int longestConsecutive(TreeNode root) { + int[] result = {0}; + helper(root, result); + return result[0]; + } + + private int[] helper(TreeNode root, int[] result) { + if (root == null) { + return new int[]{0, 0}; } - - private int[] helper(TreeNode root, int[] ans) { - if (root == null) { - return new int[]{0,0}; - } - - int increase = 1; - int decrease = 1; - - if (root.left != null) { - int[] left = helper(root.left, ans); - if (root.val == root.left.val - 1) { - increase = left[0] + 1; - } - if (root.val == root.left.val + 1) { - decrease = left[1] + 1; - } - } - - if (root.right != null) { - int[] right = helper(root.right, ans); - if (root.val == root.right.val - 1) { - increase = Math.max(right[0] + 1, increase); - } - if (root.val == root.right.val + 1) { - decrease = Math.max(right[1] + 1, decrease); - } - } - - ans[0] = Math.max(ans[0], increase + decrease - 1); - - return new int[]{increase, decrease}; + int increment = 1; + int decrement = 1; + if (root.left != null) { + int[] left = helper(root.left, result); + if (root.val == root.left.val + 1) { + decrement = left[1] + 1; + } else if (root.val == root.left.val - 1) { + increment = left[0] + 1; + } } + if (root.right != null) { + int[] right = helper(root.right, result); + if (root.val == root.right.val + 1) { + decrement = Math.max(decrement, right[1] + 1); + } else if (root.val == root.right.val - 1) { + increment = Math.max(increment, right[0] + 1); + } + } + result[0] = Math.max(result[0], increment + decrement - 1); + return new int[]{increment, decrement}; + } } diff --git a/Medium/Binary Tree Longest Consecutive Sequence.java b/Medium/Binary Tree Longest Consecutive Sequence.java index b5f278aa..92a3e1b4 100644 --- a/Medium/Binary Tree Longest Consecutive Sequence.java +++ b/Medium/Binary Tree Longest Consecutive Sequence.java @@ -4,37 +4,44 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public int longestConsecutive(TreeNode root) { - if (root == null) { - return 0; - } - - int[] ans = {1}; - helper(root, ans, null, 1); - - return ans[0]; + public int longestConsecutive(TreeNode root) { + int maxLength = 0; + Queue queue = new LinkedList<>(); + queue.add(new NodePair(root, 1)); + while (!queue.isEmpty()) { + NodePair removed = queue.remove(); + maxLength = Math.max(maxLength, removed.currLength); + if (removed.node.left != null) { + int sequenceLength = (removed.node.left.val == removed.node.val + 1 + ? removed.currLength + 1 : 1); + queue.add(new NodePair(removed.node.left, sequenceLength)); + } + if (removed.node.right != null) { + int sequenceLength = (removed.node.right.val == removed.node.val + 1 + ? removed.currLength + 1 : 1); + queue.add(new NodePair(removed.node.right, sequenceLength)); + } } + return maxLength; + } + + private class NodePair { + TreeNode node; + int currLength; - private void helper(TreeNode root, int[] ans, TreeNode parent, int count) { - if (root == null) { - return; - } - - if (parent != null) { - if (root.val == parent.val + 1) { - count++; - ans[0] = Math.max(ans[0], count); - } - else { - count = 1; - } - } - - helper(root.left, ans, root, count); - helper(root.right, ans, root, count); + public NodePair(TreeNode node, int currLength) { + this.node = node; + this.currLength = currLength; } + } } diff --git a/Medium/Binary Tree Preorder Traversal.java b/Medium/Binary Tree Preorder Traversal.java index e2f64ac4..61765340 100644 --- a/Medium/Binary Tree Preorder Traversal.java +++ b/Medium/Binary Tree Preorder Traversal.java @@ -4,31 +4,33 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { public List preorderTraversal(TreeNode root) { - ArrayList ans = new ArrayList<>(); if (root == null) { - return ans; + return List.of(); } - Stack s = new Stack<>(); - - s.push(root); - - while(s.size() > 0) { - TreeNode curr = s.pop(); - ans.add(curr.val); - if(curr.right != null) { - s.push(curr.right); + Stack stack = new Stack<>(); + stack.push(root); + List result = new ArrayList<>(); + while (!stack.isEmpty()) { + TreeNode removed = stack.pop(); + result.add(removed.val); + if (removed.right != null) { + stack.push(removed.right); } - - if(curr.left != null) { - s.push(curr.left); + if (removed.left != null) { + stack.push(removed.left); } } - - return ans; + return result; } } diff --git a/Medium/Binary Tree Pruning.java b/Medium/Binary Tree Pruning.java index 8bcf8f80..9269db06 100644 --- a/Medium/Binary Tree Pruning.java +++ b/Medium/Binary Tree Pruning.java @@ -4,32 +4,32 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public TreeNode pruneTree(TreeNode root) { - return checker(root); + public TreeNode pruneTree(TreeNode root) { + return subtreeContainsOne(root) ? root : null; + } + + private boolean subtreeContainsOne(TreeNode root) { + if (root == null) { + return false; } - -// A checker method which checks every node and makes it null if it doesn't contain a 1 - public TreeNode checker(TreeNode root) { - if (!checkForOnes(root)) { - root = null; - return root; - } - - root.left = checker(root.left); - root.right = checker(root.right); - - return root; + boolean leftContains = subtreeContainsOne(root.left); + boolean rightContains = subtreeContainsOne(root.right); + if (!leftContains) { + root.left = null; } - -// Checks for a 1 in the node - public boolean checkForOnes(TreeNode root) { - if (root == null) return false; - if (root.val == 1) return true; - - return checkForOnes(root.left) || checkForOnes(root.right); + if (!rightContains) { + root.right = null; } + return leftContains || rightContains || root.val == 1; + } } diff --git a/Medium/Binary Tree Right Side View.java b/Medium/Binary Tree Right Side View.java index 47330c6f..6aa6e40b 100644 --- a/Medium/Binary Tree Right Side View.java +++ b/Medium/Binary Tree Right Side View.java @@ -4,41 +4,38 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - List list; - public List rightSideView(TreeNode root) { - list = new ArrayList<>(); - if (root == null) { - return list; - } - - helper(root); - return list; + public List rightSideView(TreeNode root) { + if (root == null) { + return new ArrayList<>(); } - - private void helper(TreeNode root) { - Queue queue = new LinkedList<>(); - queue.add(root); - - while (!queue.isEmpty()) { - int size = queue.size(); - - for (int i=1; i<=size; i++) { - TreeNode popped = queue.remove(); - if (popped.left != null) { - queue.add(popped.left); - } - if (popped.right != null) { - queue.add(popped.right); - } - - if (i == size) { - list.add(popped.val); - } - } + List result = new ArrayList<>(); + Queue queue = new LinkedList<>(); + queue.add(root); + while (!queue.isEmpty()) { + int size = queue.size(); + int rightMostValue = -1; + while (size-- > 0) { + TreeNode removed = queue.remove(); + rightMostValue = removed.val; + if (removed.left != null) { + queue.add(removed.left); + } + if (removed.right != null) { + queue.add(removed.right); } + } + result.add(rightMostValue); } + return result; + } } diff --git a/Medium/Binary Tree Upside Down.java b/Medium/Binary Tree Upside Down.java index dde329cc..b93f1b75 100644 --- a/Medium/Binary Tree Upside Down.java +++ b/Medium/Binary Tree Upside Down.java @@ -4,35 +4,35 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public TreeNode upsideDownBinaryTree(TreeNode root) { - if (root == null || root.left == null) { - return root; - } - - TreeNode left = root.left; - TreeNode right = root.right; - - root.left = null; - root.right = null; - - return helper(left, root, right); + public TreeNode upsideDownBinaryTree(TreeNode root) { + if (root == null || root.left == null) { + return root; } - - private TreeNode helper(TreeNode rootLeft, TreeNode root, TreeNode rootRight) { - if (rootLeft == null) { - return root; - } - - TreeNode rootLeftLeft = rootLeft.left; - TreeNode rootLeftRight = rootLeft.right; - - rootLeft.left = rootRight; - rootLeft.right = root; - - return helper(rootLeftLeft, rootLeft, rootLeftRight); + TreeNode rightNode = root.right; + TreeNode leftNode = root.left; + root.left = null; + root.right = null; + return helper(root, leftNode, rightNode); + } + + private TreeNode helper(TreeNode root, TreeNode leftNode, TreeNode rightNode) { + if (leftNode == null) { + return root; } + TreeNode leftNodeLeft = leftNode.left; + TreeNode leftNodeRight = leftNode.right; + leftNode.left = rightNode; + leftNode.right = root; + return helper(leftNode, leftNodeLeft, leftNodeRight); + } } diff --git a/Medium/Binary Tree Vertical Order Traversal.java b/Medium/Binary Tree Vertical Order Traversal.java index 93c1004a..5d0e954f 100644 --- a/Medium/Binary Tree Vertical Order Traversal.java +++ b/Medium/Binary Tree Vertical Order Traversal.java @@ -36,15 +36,15 @@ public List> verticalOrder(TreeNode root) { } return new ArrayList<>(map.values()); } -} + + private class TreeLevel { + TreeNode node; + int level; -class TreeLevel { - TreeNode node; - int level; - - public TreeLevel(TreeNode node, int level) { - this.node = node; - this.level = level; + public TreeLevel(TreeNode node, int level) { + this.node = node; + this.level = level; + } } } diff --git a/Medium/Binary Trees With Factors.java b/Medium/Binary Trees With Factors.java new file mode 100644 index 00000000..be7e38be --- /dev/null +++ b/Medium/Binary Trees With Factors.java @@ -0,0 +1,29 @@ +class Solution { + private final int MOD = 1_000_000_007; + + public int numFactoredBinaryTrees(int[] arr) { + int n = arr.length; + Arrays.sort(arr); + long[] dp = new long[n]; + Arrays.fill(dp, 1); + Map indexMap = new HashMap<>(); + for (int i = 0; i < n; i++) { + indexMap.put(arr[i], i); + } + for (int i = 0; i < n; i++) { + for (int j = 0; j < i; j++) { + if (arr[i] % arr[j] == 0) { + int right = arr[i] / arr[j]; + if (indexMap.containsKey(right)) { + dp[i] = (dp[i] + dp[j] * dp[indexMap.get(right)]) % MOD; + } + } + } + } + long result = 0; + for (long count : dp) { + result += count; + } + return (int) (result % MOD); + } +} diff --git a/Medium/Bitwise AND of Numbers Range.java b/Medium/Bitwise AND of Numbers Range.java index a5823908..c0645dd1 100644 --- a/Medium/Bitwise AND of Numbers Range.java +++ b/Medium/Bitwise AND of Numbers Range.java @@ -1,34 +1,8 @@ class Solution { - public int rangeBitwiseAnd(int m, int n) { - int temp1 = m; - int temp2 = n; - - int cnt1 = 0; - int cnt2 = 0; - - while (temp1 > 1 || temp2 > 1) { - if (temp1 > 1) { - temp1 /= 2; - cnt1++; - } - - if (temp2 > 1) { - temp2 /= 2; - cnt2++; - } - } - - if (cnt1 != cnt2) { - return 0; - } - - int res = ~0; - for (int i=m;i left) { + right = right & (right - 1); } + return left & right; + } } diff --git a/Medium/Bitwise XOR of All Pairings.java b/Medium/Bitwise XOR of All Pairings.java new file mode 100644 index 00000000..88dfbd41 --- /dev/null +++ b/Medium/Bitwise XOR of All Pairings.java @@ -0,0 +1,20 @@ +class Solution { + public int xorAllNums(int[] nums1, int[] nums2) { + int m = nums1.length; + int n = nums2.length; + Map freq = new HashMap<>(); + for (int num : nums1) { + freq.put(num, freq.getOrDefault(num, 0) + n); + } + for (int num : nums2) { + freq.put(num, freq.getOrDefault(num, 0) + m); + } + int result = 0; + for (Integer key : freq.keySet()) { + if (freq.get(key) % 2 == 1) { + result ^= key; + } + } + return result; + } +} diff --git a/Medium/Boats to Save People.java b/Medium/Boats to Save People.java index 365bafc0..dab79035 100644 --- a/Medium/Boats to Save People.java +++ b/Medium/Boats to Save People.java @@ -1,16 +1,16 @@ class Solution { - public int numRescueBoats(int[] people, int limit) { - Arrays.sort(people); - int count = 0; - int start = 0; - int end = people.length - 1; - while (end >= start) { - if (people[start] + people[end] <= limit) { - start++; - } - end--; - count++; + public int numRescueBoats(int[] people, int limit) { + Arrays.sort(people); + int left = 0; + int right = people.length - 1; + int count = 0; + while (left <= right) { + int capacity = people[right--]; + if (left <= right && capacity + people[left] <= limit) { + left++; + } + count++; + } + return count; } - return count; - } } diff --git a/Medium/Bold Words in String.java b/Medium/Bold Words in String.java new file mode 100644 index 00000000..3e19c0a0 --- /dev/null +++ b/Medium/Bold Words in String.java @@ -0,0 +1,44 @@ +class Solution { + public String boldWords(String[] words, String s) { + List indexes = new ArrayList<>(); + for (String word : words) { + indexes.addAll(getIndexPair(s, word)); + } + Collections.sort(indexes, + Comparator.comparingInt((int[] o) -> o[0]).thenComparingInt(o -> o[1])); + Set startIdx = new HashSet<>(); + Set endIdx = new HashSet<>(); + int idx = 0; + while (idx < indexes.size()) { + int currStart = indexes.get(idx)[0]; + int currEnd = indexes.get(idx)[1]; + idx++; + while (idx < indexes.size() && indexes.get(idx)[0] <= currEnd + 1) { + currEnd = Math.max(currEnd, indexes.get(idx++)[1]); + } + startIdx.add(currStart); + endIdx.add(currEnd); + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + if (startIdx.contains(i)) { + sb.append(""); + } + sb.append(s.charAt(i)); + if (endIdx.contains(i)) { + sb.append(""); + } + } + return sb.toString(); + } + + private List getIndexPair(String s, String word) { + List indexPairs = new ArrayList<>(); + for (int i = 0; i < s.length() - word.length() + 1; i++) { + if (s.startsWith(word, i)) { + indexPairs.add(new int[]{i, i + word.length() - 1}); + } + } + return indexPairs; + } +} diff --git a/Medium/Bomb Enemy.java b/Medium/Bomb Enemy.java new file mode 100644 index 00000000..c6259b7a --- /dev/null +++ b/Medium/Bomb Enemy.java @@ -0,0 +1,42 @@ +class Solution { + public int maxKilledEnemies(char[][] grid) { + if (grid.length == 0) { + return 0; + } + int rows = grid.length; + int cols = grid[0].length; + int maxCount = 0; + int rowHits = 0; + int[] colHits = new int[cols]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (j == 0 || grid[i][j - 1] == 'W') { + rowHits = 0; + for (int k = j; k < cols; k++) { + if (grid[i][k] == 'W') { + break; + } + if (grid[i][k] == 'E') { + rowHits++; + } + } + } + if (i == 0 || grid[i - 1][j] == 'W') { + colHits[j] = 0; + for (int k = i; k < rows; k++) { + if (grid[k][j] == 'W') { + break; + } + if (grid[k][j] == 'E') { + colHits[j]++; + } + } + } + if (grid[i][j] == '0') { + maxCount = Math.max(maxCount, rowHits + colHits[j]); + } + } + } + return maxCount; + } +} diff --git a/Medium/Boundary of Binary Tree.java b/Medium/Boundary of Binary Tree.java index 565dc467..a6e26f56 100644 --- a/Medium/Boundary of Binary Tree.java +++ b/Medium/Boundary of Binary Tree.java @@ -4,57 +4,75 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - List list; - List rightVal; public List boundaryOfBinaryTree(TreeNode root) { - list = new ArrayList<>(); - rightVal = new ArrayList<>(); - if (root == null) { - return list; + List result = new ArrayList<>(); + if (!isLeaf(root)) { + result.add(root.val); } - if (root.left == null && root.right == null) { - list.add(root.val); - return list; + if (root.left != null) { + addLeft(result, root.left); } - list.add(root.val); - addLeft(root.left); - addLeaves(root); - addRight(root.right); - for (int i = rightVal.size() - 1; i >= 0; i--) { - list.add(rightVal.get(i)); + addLeaves(result, root); + if (root.right != null) { + addRight(result, root.right); } - return list; + return result; } - private void addLeft(TreeNode left) { - if (left == null || (left.left == null && left.right == null)) { - return; + private void addRight(List result, TreeNode node) { + Stack stack = new Stack<>(); + while (node != null) { + if (!isLeaf(node)) { + stack.push(node.val); + } + if (node.right != null) { + node = node.right; + } else { + node = node.left; + } + } + while (!stack.isEmpty()) { + result.add(stack.pop()); } - list.add(left.val); - addLeft(left.left == null ? left.right : left.left); } - private void addLeaves(TreeNode root) { - if (root == null) { - return; - } - if (root.left == null && root.right == null) { - list.add(root.val); - return; + private void addLeft(List result, TreeNode node) { + while (node != null) { + if (!isLeaf(node)) { + result.add(node.val); + } + if (node.left != null) { + node = node.left; + } else { + node = node.right; + } } - addLeaves(root.left); - addLeaves(root.right); } - private void addRight(TreeNode right) { - if (right == null || (right.left == null && right.right == null)) { - return; + private void addLeaves(List result, TreeNode root) { + if (isLeaf(root)) { + result.add(root.val); + } else { + if (root.left != null) { + addLeaves(result, root.left); + } + if (root.right != null) { + addLeaves(result, root.right); + } } - rightVal.add(right.val); - addRight(right.right == null ? right.left : right.right); } + + private boolean isLeaf(TreeNode node) { + return node.left == null && node.right == null; + } } diff --git a/Medium/Brace Expansion.java b/Medium/Brace Expansion.java new file mode 100644 index 00000000..38f0d5a4 --- /dev/null +++ b/Medium/Brace Expansion.java @@ -0,0 +1,47 @@ +class Solution { + public String[] expand(String s) { + List> splits = parseInput(s); + List result = new ArrayList<>(); + StringBuilder sb = new StringBuilder(); + helper(splits, result, sb, 0); + Collections.sort(result); + String[] answer = new String[result.size()]; + for (int i = 0; i < result.size(); i++) { + answer[i] = result.get(i); + } + return answer; + } + + private void helper(List> splits, List result, StringBuilder sb, int idx) { + if (idx >= splits.size()) { + if (sb.length() == splits.size()) { + result.add(new StringBuilder(sb.toString()).toString()); + } + } else { + for (int i = idx; i < splits.size(); i++) { + List currentSplit = splits.get(i); + for (String section : currentSplit) { + sb.append(section); + helper(splits, result, sb, i + 1); + sb.deleteCharAt(sb.length() - 1); + } + } + } + } + + private List> parseInput(String s) { + List> splits = new ArrayList<>(); + int idx = 0; + while (idx < s.length()) { + if (s.charAt(idx) == '{') { + int endIdx = s.indexOf('}', idx); + String[] segements = s.substring(idx + 1, endIdx).split(","); + splits.add(Arrays.asList(segements)); + idx = endIdx + 1; + } else { + splits.add(List.of(String.valueOf(s.charAt(idx++)))); + } + } + return splits; + } +} diff --git a/Medium/Break a Palindrome.java b/Medium/Break a Palindrome.java index eca6bb8b..3da29e2e 100644 --- a/Medium/Break a Palindrome.java +++ b/Medium/Break a Palindrome.java @@ -1,24 +1,14 @@ class Solution { public String breakPalindrome(String palindrome) { - // If empty or of length 1 => return empty - if (palindrome.length() <= 1) { + if (palindrome.length() == 1) { return ""; } - char[] chars = palindrome.toCharArray(); - for (int i = 0; i < chars.length; i++) { - if (chars[i] != 'a') { - // Skip if the string is of odd length and it is the middle index - if (palindrome.length() % 2 != 0 && i == palindrome.length() / 2) { - continue; - } - chars[i] = 'a'; - break; - } - // If all chars all 'a' update last char to 'b' - if (i == chars.length - 1) { - chars[i] = 'b'; + for (int i = 0; i < palindrome.length(); i++) { + if (palindrome.charAt(i) != 'a' && + (palindrome.length() % 2 == 0 || i != palindrome.length() / 2)) { + return palindrome.substring(0, i) + "a" + palindrome.substring(i + 1); } } - return String.valueOf(chars); + return palindrome.substring(0, palindrome.length() - 1) + "b"; } } diff --git a/Medium/Broken Calculator.java b/Medium/Broken Calculator.java index 9b89d8c0..ea40c3e7 100644 --- a/Medium/Broken Calculator.java +++ b/Medium/Broken Calculator.java @@ -1,18 +1,14 @@ class Solution { - public int brokenCalc(int X, int Y) { - int count = 0; - - while (Y > X) { - if (Y % 2 == 0) { - Y = Y / 2; - } - else { - Y++; - } - - count++; - } - - return count + X - Y; + public int brokenCalc(int startValue, int target) { + int numOfSteps = 0; + while (target > startValue) { + numOfSteps++; + if (target % 2 == 1) { + target++; + } else { + target /= 2; + } } + return numOfSteps + startValue - target; + } } diff --git a/Medium/Build an Array With Stack Operations.java b/Medium/Build an Array With Stack Operations.java new file mode 100644 index 00000000..f36177cd --- /dev/null +++ b/Medium/Build an Array With Stack Operations.java @@ -0,0 +1,23 @@ +class Solution { + + private static final String PUSH = "Push"; + private static final String POP = "Pop"; + + public List buildArray(int[] target, int n) { + int idx = 0; + List result = new ArrayList<>(); + for (int i = 1; i <= n; i++) { + if (target[idx] == i) { + idx++; + result.add(PUSH); + } else { + result.add(PUSH); + result.add(POP); + } + if (idx == target.length) { + break; + } + } + return result; + } +} diff --git a/Medium/Buildings With an Ocean View.java b/Medium/Buildings With an Ocean View.java new file mode 100644 index 00000000..6d52576e --- /dev/null +++ b/Medium/Buildings With an Ocean View.java @@ -0,0 +1,18 @@ +class Solution { + public int[] findBuildings(int[] heights) { + List result = new ArrayList<>(); + int maxHeight = -1; + for (int i = heights.length - 1; i >= 0; i--) { + if (heights[i] > maxHeight) { + result.add(i); + } + maxHeight = Math.max(maxHeight, heights[i]); + } + int[] ans = new int[result.size()]; + Collections.reverse(result); + for (int i = 0; i < result.size(); i++) { + ans[i] = result.get(i); + } + return ans; + } +} diff --git a/Medium/Calculate Score After Performing Instructions.java b/Medium/Calculate Score After Performing Instructions.java new file mode 100644 index 00000000..789e5669 --- /dev/null +++ b/Medium/Calculate Score After Performing Instructions.java @@ -0,0 +1,19 @@ +class Solution { + public long calculateScore(String[] instructions, int[] values) { + long result = 0; + int n = values.length; + int idx = 0; + Set executed = new HashSet<>(); + while (idx < n && idx >= 0) { + if (!executed.add(idx)) { + break; + } + if (instructions[idx].equals("add")) { + result += values[idx++]; + } else { + idx += values[idx]; + } + } + return result; + } +} diff --git a/Medium/Campus Bikes II.java b/Medium/Campus Bikes II.java index 82de40c4..692725d0 100644 --- a/Medium/Campus Bikes II.java +++ b/Medium/Campus Bikes II.java @@ -1,30 +1,28 @@ class Solution { - int minDist; - public int assignBikes(int[][] workers, int[][] bikes) { - minDist = Integer.MAX_VALUE; - dfs(new boolean[bikes.length], workers, 0, bikes, 0); - return minDist; - } - - private void dfs(boolean[] visited, int[][] workers, int currIdx, int[][] bikes, int distance) { - if (currIdx >= workers.length) { - minDist = Math.min(minDist, distance); - return; + public int assignBikes(int[][] workers, int[][] bikes) { + Integer[] dp = new Integer[1024]; + return minDistance(workers, bikes, 0, 0, dp); } - if (distance > minDist) { - return; + + private int minDistance(int[][] workers, int[][] bikes, int workerIdx, int mask, Integer[] dp) { + if (workerIdx >= workers.length) { + return 0; + } + if (dp[mask] != null) { + return dp[mask]; + } + int distance = Integer.MAX_VALUE; + for (int i = 0; i < bikes.length; i++) { + // if bike is available + if ((mask & (1 << i)) == 0) { + // assign the bike & traverse for remaining bikes + distance = Math.min(distance, calculateManhattanDistance(workers[workerIdx], bikes[i]) + minDistance(workers, bikes, workerIdx + 1, mask | (1 << i), dp)); + } + } + return dp[mask] = distance; } - for (int i = 0; i < bikes.length; i++) { - if (visited[i]) { - continue; - } - visited[i] = true; - dfs(visited, workers, currIdx + 1, bikes, distance + getManahattanDist(bikes[i], workers[currIdx])); - visited[i] = false; + + private static int calculateManhattanDistance(int[] worker, int[] bike) { + return Math.abs(worker[0] - bike[0]) + Math.abs(worker[1] - bike[1]); } - } - - private int getManahattanDist(int[] p1, int[] p2) { - return Math.abs(p1[0] - p2[0]) + Math.abs(p1[1] - p2[1]); - } } diff --git a/Medium/Campus Bikes.java b/Medium/Campus Bikes.java index 9d385afb..129f4fbc 100644 --- a/Medium/Campus Bikes.java +++ b/Medium/Campus Bikes.java @@ -1,46 +1,39 @@ class Solution { - public int[] assignBikes(int[][] workers, int[][] bikes) { - PriorityQueue pq = new PriorityQueue<>(new Comparator(){ - public int compare(Node n1, Node n2) { - int c = n1.dist - n2.dist; - if (c != 0) { - return c; + public int[] assignBikes(int[][] workers, int[][] bikes) { + int workerCount = workers.length; + int bikeCount = bikes.length; + PriorityQueue priorityQueue = new PriorityQueue<>(); + for (int i = 0; i < workerCount; i++) { + for (int j = 0; j < bikeCount; j++) { + priorityQueue.add(new WorkerBikePair(manhattanDistance(workers[i], bikes[j]), i, j)); + } } - c = n1.workIdx - n2.workIdx; - return c != 0 ? c : n1.cycleIdx - n2.cycleIdx; - } - }); - for (int i = 0; i < workers.length; i++) { - for (int j = 0; j < bikes.length; j++) { - pq.add(new Node(getDist(workers[i], bikes[j]), i, j)); - } + Set bikeDone = new HashSet<>(); + int[] result = new int[workerCount]; + Arrays.fill(result, Integer.MIN_VALUE); + while (!priorityQueue.isEmpty()) { + WorkerBikePair removed = priorityQueue.remove(); + if (result[removed.workerIdx] == Integer.MIN_VALUE && !bikeDone.contains(removed.bikeIdx)) { + result[removed.workerIdx] = removed.bikeIdx; + bikeDone.add(removed.bikeIdx); + } + } + return result; } - int[] ans = new int[workers.length]; - boolean[] bikesTaken = new boolean[bikes.length]; - Arrays.fill(ans, Integer.MIN_VALUE); - while (!pq.isEmpty()) { - Node node = pq.remove(); - if (ans[node.workIdx] == Integer.MIN_VALUE && !bikesTaken[node.cycleIdx]) { - ans[node.workIdx] = node.cycleIdx; - bikesTaken[node.cycleIdx] = true; - } + + private record WorkerBikePair(int manhattanDistance, int workerIdx, int bikeIdx) implements Comparable { + @Override + public int compareTo(WorkerBikePair o) { + int c = manhattanDistance - o.manhattanDistance; + if (c != 0) { + return c; + } + c = workerIdx - o.workerIdx; + return c != 0 ? c : bikeIdx - o.bikeIdx; + } } - return ans; - } - - private int getDist(int[] p1, int[] p2) { - return Math.abs(p1[0] - p2[0]) + Math.abs(p1[1] - p2[1]); - } -} -class Node { - int dist; - int workIdx; - int cycleIdx; - - public Node(int dist, int workIdx, int cycleIdx) { - this.dist = dist; - this.workIdx = workIdx; - this.cycleIdx = cycleIdx; - } + private static int manhattanDistance(int[] p1, int[] p2) { + return Math.abs(p1[0] - p2[0]) + Math.abs(p1[1] - p2[1]); + } } diff --git a/Medium/Capacity To Ship Packages Within D Days.java b/Medium/Capacity To Ship Packages Within D Days.java index 8b3b587f..8d7ff38e 100644 --- a/Medium/Capacity To Ship Packages Within D Days.java +++ b/Medium/Capacity To Ship Packages Within D Days.java @@ -1,29 +1,31 @@ class Solution { - public int shipWithinDays(int[] weights, int D) { - int maxWeight = weights[0]; - int totalWeight = 0; + public int shipWithinDays(int[] weights, int days) { + int maximumWeight = 0; + int minimumWeight = weights[0]; for (int weight : weights) { - maxWeight = Math.max(maxWeight, weight); - totalWeight += weight; + maximumWeight += weight; + minimumWeight = Math.max(minimumWeight, weight); } - while (maxWeight < totalWeight) { - int midWeight = (maxWeight + totalWeight) / 2; - int need = 1; - int curr = 0; - for (int weight : weights) { - if (curr + weight > midWeight) { - need += 1; - curr = 0; - } - curr += weight; + while (minimumWeight <= maximumWeight) { + int currCapacity = (maximumWeight + minimumWeight) / 2; + if (isShipmentPossible(weights, days, currCapacity)) { + maximumWeight = currCapacity - 1; + } else { + minimumWeight = currCapacity + 1; } - if (need > D) { - maxWeight = midWeight + 1; - } - else { - totalWeight = midWeight; + } + return minimumWeight; + } + + private boolean isShipmentPossible(int[] weights, int days, int capacity) { + int idx = 0; + while (idx < weights.length) { + int currWeight = 0; + while (idx < weights.length && currWeight + weights[idx] <= capacity) { + currWeight += weights[idx++]; } + days--; } - return maxWeight; + return days >= 0; } } diff --git a/Medium/Car Pooling.java b/Medium/Car Pooling.java index ab96c443..9d09b2c4 100644 --- a/Medium/Car Pooling.java +++ b/Medium/Car Pooling.java @@ -1,20 +1,16 @@ class Solution { public boolean carPooling(int[][] trips, int capacity) { Arrays.sort(trips, Comparator.comparingInt(o -> o[1])); - int start = 0; - int idx = 0; - int n = trips.length; - int currCapacity = 0; - PriorityQueue pq = new PriorityQueue<>((a, b) -> a[2] - b[2]); - while (idx < n) { - while (!pq.isEmpty() && pq.peek()[2] <= trips[idx][1]) { - currCapacity -= pq.poll()[0]; + PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt(a -> a[2])); + for (int[] trip : trips) { + while (!pq.isEmpty() && pq.peek()[2] <= trip[1]) { + capacity += pq.poll()[0]; } - if (currCapacity + trips[idx][0] > capacity) { + if (capacity < trip[0]) { return false; } - currCapacity += trips[idx][0]; - pq.add(trips[idx++]); + pq.add(trip); + capacity -= trip[0]; } return true; } diff --git a/Medium/Champagne Tower.java b/Medium/Champagne Tower.java new file mode 100644 index 00000000..ccd07a8b --- /dev/null +++ b/Medium/Champagne Tower.java @@ -0,0 +1,13 @@ +class Solution { + public double champagneTower(int poured, int query_row, int query_glass) { + double[] glass = new double[query_row + 2]; + glass[0] = poured; + for (int row = 1; row <= query_row; row++) { + for (int idx = row; idx >= 0; idx--) { + glass[idx] = Math.max(0.0, (glass[idx] - 1) / 2); + glass[idx + 1] += glass[idx]; + } + } + return Math.min(glass[query_glass], 1.0); + } +} diff --git a/Medium/Cheapest Flights Within K Stops.java b/Medium/Cheapest Flights Within K Stops.java new file mode 100644 index 00000000..e937fdaf --- /dev/null +++ b/Medium/Cheapest Flights Within K Stops.java @@ -0,0 +1,32 @@ +class Solution { + public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) { + Map> graph = new HashMap<>(); + for (int[] flight : flights) { + graph.computeIfAbsent(flight[0], ArrayList::new).add(new int[]{flight[1], flight[2]}); + } + int[] price = new int[n]; + Arrays.fill(price, Integer.MAX_VALUE); + Queue queue = new LinkedList<>(); + queue.add(new int[]{src, 0}); + while (k-- >= 0 && !queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + int[] removed = queue.remove(); + int currCity = removed[0]; + int currPrice = removed[1]; + if (!graph.containsKey(currCity)) { + continue; + } + for (int[] node : graph.get(currCity)) { + int nextCity = node[0]; + int flightPrice = node[1]; + if (currPrice + flightPrice < price[nextCity]) { + price[nextCity] = currPrice + flightPrice; + queue.add(new int[]{nextCity, price[nextCity]}); + } + } + } + } + return price[dst] == Integer.MAX_VALUE ? -1 : price[dst]; + } +} diff --git a/Medium/Check Completeness of a Binary Tree.java b/Medium/Check Completeness of a Binary Tree.java index a0f1e5f5..2d0c94f0 100644 --- a/Medium/Check Completeness of a Binary Tree.java +++ b/Medium/Check Completeness of a Binary Tree.java @@ -14,28 +14,23 @@ * } */ class Solution { - public boolean isCompleteTree(TreeNode root) { - List nodes = new ArrayList<>(); - nodes.add(new HelperNode(root, 1)); - int idx = 0 ; - while (idx < nodes.size()) { - HelperNode hnode = nodes.get(idx++); - if (hnode.node != null) { - nodes.add(new HelperNode(hnode.node.left, 2 * hnode.level)); - nodes.add(new HelperNode(hnode.node.right, 2 * hnode.level + 1)); - } + public boolean isCompleteTree(TreeNode root) { + Queue queue = new LinkedList<>(); + boolean isEnd = false; + queue.add(root); + while (!queue.isEmpty()) { + TreeNode removed = queue.remove(); + if (removed == null) { + isEnd = true; + } + if (removed != null) { + if (isEnd) { + return false; + } + queue.add(removed.left); + queue.add(removed.right); + } + } + return true; } - return nodes.get(idx - 1).level == nodes.size(); - } -} - - -class HelperNode { - TreeNode node; - int level; - - public HelperNode(TreeNode node, int level) { - this.node = node; - this.level = level; - } } diff --git a/Medium/Check If All 1's Are at Least Length K Places Away.java b/Medium/Check If All 1's Are at Least Length K Places Away.java new file mode 100644 index 00000000..bc272afa --- /dev/null +++ b/Medium/Check If All 1's Are at Least Length K Places Away.java @@ -0,0 +1,13 @@ +class Solution { + public boolean kLengthApart(int[] nums, int k) { + for (int start = -1, idx = 0; idx < nums.length; idx++) { + if (nums[idx] == 1) { + if (start != -1 && idx - start - 1 < k) { + return false; + } + start = idx; + } + } + return true; + } +} diff --git a/Medium/Check If Array Pairs Are Divisible by k.java b/Medium/Check If Array Pairs Are Divisible by k.java new file mode 100644 index 00000000..d942915f --- /dev/null +++ b/Medium/Check If Array Pairs Are Divisible by k.java @@ -0,0 +1,20 @@ +class Solution { + public boolean canArrange(int[] arr, int k) { + Map map = new HashMap<>(); + for (int num : arr) { + int remainder = ((num % k) + k) % k; + map.put(remainder, map.getOrDefault(remainder, 0) + 1); + } + for (int num : arr) { + int remainder = ((num % k) + k) % k; + if (remainder == 0) { + if (map.get(remainder) % 2 == 1) { + return false; + } + } else if (!map.get(remainder).equals(map.get(k - remainder))) { + return false; + } + } + return true; + } +} diff --git a/Medium/Check If a String Can Break Another String.java b/Medium/Check If a String Can Break Another String.java new file mode 100644 index 00000000..0e9e9f55 --- /dev/null +++ b/Medium/Check If a String Can Break Another String.java @@ -0,0 +1,30 @@ +class Solution { + public boolean checkIfCanBreak(String s1, String s2) { + int n = s1.length(); + int[] counterS1 = new int[26]; + int[] counterS2 = new int[26]; + for (int idx = 0; idx < n; idx++) { + counterS1[s1.charAt(idx) - 'a']++; + counterS2[s2.charAt(idx) - 'a']++; + } + int countS1 = 0; + int countS2 = 0; + int side = 0; + for (int idx = 0; idx < 26; idx++) { + countS1 += counterS1[idx]; + countS2 += counterS2[idx]; + if (countS1 > countS2) { + if (side == 1) { + return false; + } + side = -1; + } else if (countS2 > countS1) { + if (side == -1) { + return false; + } + side = 1; + } + } + return true; + } +} diff --git a/Medium/Check If a String Contains All Binary Codes of Size K.java b/Medium/Check If a String Contains All Binary Codes of Size K.java new file mode 100644 index 00000000..d202d57c --- /dev/null +++ b/Medium/Check If a String Contains All Binary Codes of Size K.java @@ -0,0 +1,17 @@ +class Solution { + public boolean hasAllCodes(String s, int k) { + Set set = new HashSet<>(); + int counter = 1 << k; + for (int i = k; i <= s.length(); i++) { + String temp = s.substring(i - k, i); + if (!set.contains(temp)) { + set.add(temp); + counter--; + } + if (counter == 0) { + return true; + } + } + return false; + } +} diff --git a/Medium/Check if Strings Can be Made Equal With Operations II.java b/Medium/Check if Strings Can be Made Equal With Operations II.java new file mode 100644 index 00000000..7507b140 --- /dev/null +++ b/Medium/Check if Strings Can be Made Equal With Operations II.java @@ -0,0 +1,21 @@ +class Solution { + public boolean checkStrings(String s1, String s2) { + int[] odd = new int[26]; + int[] even = new int[26]; + for (int i = 0; i < s1.length(); i++) { + if (i % 2 == 0) { + even[s1.charAt(i) - 'a']++; + even[s2.charAt(i) - 'a']--; + } else { + odd[s1.charAt(i) - 'a']++; + odd[s2.charAt(i) - 'a']--; + } + } + for (int i = 0; i < 26; i++) { + if (odd[i] != 0 || even[i] != 0) { + return false; + } + } + return true; + } +} diff --git a/Medium/Check if a Parentheses String Can Be Valid.java b/Medium/Check if a Parentheses String Can Be Valid.java new file mode 100644 index 00000000..c240176d --- /dev/null +++ b/Medium/Check if a Parentheses String Can Be Valid.java @@ -0,0 +1,30 @@ +class Solution { + public boolean canBeValid(String s, String locked) { + if (s.length() % 2 != 0) { + return false; + } + Stack openBrackets = new Stack<>(); + Stack unlocked = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (locked.charAt(i) == '0') { + unlocked.push(i); + } else if (c == '(') { + openBrackets.push(i); + } else if (c == ')') { + if (!openBrackets.isEmpty()) { + openBrackets.pop(); + } else if (!unlocked.isEmpty()) { + unlocked.pop(); + } else { + return false; + } + } + } + while (!openBrackets.isEmpty() && !unlocked.isEmpty() && openBrackets.peek() < unlocked.peek()) { + openBrackets.pop(); + unlocked.pop(); + } + return openBrackets.isEmpty(); + } +} diff --git a/Medium/Clone Binary Tree With Random Pointer.java b/Medium/Clone Binary Tree With Random Pointer.java index 922389ca..cf43c71a 100644 --- a/Medium/Clone Binary Tree With Random Pointer.java +++ b/Medium/Clone Binary Tree With Random Pointer.java @@ -1,5 +1,5 @@ /** - * Definition for a binary tree node. + * Definition for Node. * public class Node { * int val; * Node left; @@ -15,33 +15,45 @@ * } * } */ + class Solution { - Map copyMap; - public NodeCopy copyRandomBinaryTree(Node root) { - copyMap = new HashMap<>(); - fillMapTraverse(root); - cloneMapTraverse(root); - return copyMap.get(root); - } - - private void cloneMapTraverse(Node root) { - if (root == null) { - return; + public NodeCopy copyRandomBinaryTree(Node root) { + if (root == null) { + return null; + } + Map map = new HashMap<>(); + copyOnlyNode(root, map); + copyNodePointers(root, map); + return map.get(root); } - NodeCopy copy = copyMap.get(root); - copy.left = copyMap.get(root.left); - copy.right = copyMap.get(root.right); - copy.random = copyMap.get(root.random); - cloneMapTraverse(root.left); - cloneMapTraverse(root.right); - } - - private void fillMapTraverse(Node root) { - if (root == null) { - return; + + private void copyNodePointers(Node root, Map map) { + Queue queue = new LinkedList<>(); + queue.add(root); + while (!queue.isEmpty()) { + Node removed = queue.remove(); + NodeCopy copied = map.get(removed); + if (removed.left != null) { + queue.add(removed.left); + copied.left = map.get(removed.left); + } + if (removed.right != null) { + queue.add(removed.right); + copied.right = map.get(removed.right); + } + if (removed.random != null) { + copied.random = map.get(removed.random); + } + } + } + + private void copyOnlyNode(Node root, Map map) { + if (root == null) { + return; + } + NodeCopy copiedNode = new NodeCopy(root.val); + map.put(root, copiedNode); + copyOnlyNode(root.left, map); + copyOnlyNode(root.right, map); } - copyMap.put(root, new NodeCopy(root.val)); - fillMapTraverse(root.left); - fillMapTraverse(root.right); - } } diff --git a/Medium/Clone Graph.java b/Medium/Clone Graph.java index 1c116288..cddb7b81 100644 --- a/Medium/Clone Graph.java +++ b/Medium/Clone Graph.java @@ -3,17 +3,14 @@ class Node { public int val; public List neighbors; - public Node() { val = 0; neighbors = new ArrayList(); } - public Node(int _val) { val = _val; neighbors = new ArrayList(); } - public Node(int _val, ArrayList _neighbors) { val = _val; neighbors = _neighbors; @@ -22,24 +19,24 @@ public Node(int _val, ArrayList _neighbors) { */ class Solution { - public Node cloneGraph(Node node) { - if (node == null) { - return null; - } - Map map = new HashMap<>(); - Queue queue = new LinkedList<>(); - queue.add(node); - map.put(node, new Node(node.val, new ArrayList<>())); - while (!queue.isEmpty()) { - Node removed = queue.remove(); - for (Node neighbor : removed.neighbors) { - if (!map.containsKey(neighbor)) { - map.put(neighbor, new Node(neighbor.val, new ArrayList<>())); - queue.add(neighbor); + public Node cloneGraph(Node node) { + if (node == null) { + return null; + } + Map map = new HashMap(); + Queue queue = new LinkedList<>(); + queue.add(node); + map.put(node, new Node(node.val)); + while (!queue.isEmpty()) { + Node removed = queue.remove(); + for (Node neighbor : removed.neighbors) { + if (!map.containsKey(neighbor)) { + map.put(neighbor, new Node(neighbor.val)); + queue.add(neighbor); + } + map.get(removed).neighbors.add(map.get(neighbor)); + } } - map.get(removed).neighbors.add(map.get(neighbor)); - } + return map.get(node); } - return map.get(node); - } } diff --git a/Medium/Clone N-ary Tree.java b/Medium/Clone N-ary Tree.java index 3943e23c..819cb14d 100644 --- a/Medium/Clone N-ary Tree.java +++ b/Medium/Clone N-ary Tree.java @@ -24,43 +24,23 @@ public Node(int _val,ArrayList _children) { class Solution { public Node cloneTree(Node root) { if (root == null) { - return null; + return root; } - Node copy = new Node(root.val); - for (Node child : root.children) { - copy.children.add(cloneTree(child)); - } - return copy; - } - - Map map; - public Node cloneTreeDetailed(Node root) { - if (root == null) { - return null; - } - map = new HashMap<>(); - copyTree(root); Queue queue = new LinkedList<>(); + Map map = new HashMap<>(); queue.add(root); + map.put(root, new Node(root.val)); while (!queue.isEmpty()) { - Node removed = queue.remove(); - Node copy = map.get(removed); - List children = removed.children; - for (Node child : children) { - copy.children.add(map.get(child)); - queue.add(child); + int size = queue.size(); + while (size-- > 0) { + Node removed = queue.remove(); + for (Node child : removed.children) { + queue.add(child); + map.put(child, new Node(child.val)); + map.get(removed).children.add(map.get(child)); + } } } return map.get(root); } - - private void copyTree(Node root) { - if (root == null) { - return; - } - map.put(root, new Node(root.val)); - for (Node child : root.children) { - copyTree(child); - } - } } diff --git a/Medium/Closest Nodes Queries in a Binary Search Tree.java b/Medium/Closest Nodes Queries in a Binary Search Tree.java new file mode 100644 index 00000000..e1c19211 --- /dev/null +++ b/Medium/Closest Nodes Queries in a Binary Search Tree.java @@ -0,0 +1,37 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public List> closestNodes(TreeNode root, List queries) { + TreeSet set = new TreeSet<>(); + traverse(root, set); + List> result = new ArrayList<>(); + for (Integer query : queries) { + Integer lower = set.floor(query); + Integer upper = set.ceiling(query); + result.add(Arrays.asList((lower == null ? -1 : lower), (upper == null ? -1 : upper))); + } + return result; + } + + private void traverse(TreeNode root, TreeSet set) { + if (root == null) { + return; + } + set.add(root.val); + traverse(root.left, set); + traverse(root.right, set); + } +} diff --git a/Medium/Coin Change.java b/Medium/Coin Change.java index e5bfb1f1..f728e957 100644 --- a/Medium/Coin Change.java +++ b/Medium/Coin Change.java @@ -1,29 +1,57 @@ class Solution { public int coinChange(int[] coins, int amount) { - if (amount < 1) { + Integer[] dp = new Integer[amount + 1]; + Arrays.fill(dp, amount + 1); + dp[0] = 0; + for (int i = 1; i <= amount; i++) { + for (int coin : coins) { + if (i - coin < 0) { + continue; + } + dp[i] = Math.min(dp[i], dp[i - coin] + 1); + } + } + return dp[amount] == (amount + 1) ? -1 : dp[amount]; + } + + private int coinChangeMemoization(int[] coins, int amount, Integer[] memo) { + if (amount < 0) { + return -1; + } + if (amount == 0) { return 0; } - return coinChange(coins, amount, new int[amount]); + if (memo[amount] != null) { + return memo[amount]; + } + int minCount = Integer.MAX_VALUE; + for (int coin : coins) { + int count = coinChangeMemoization(coins, amount - coin, memo); + if (count == -1) { + continue; + } + minCount = Math.min(minCount, count + 1); + } + memo[amount] = minCount == Integer.MAX_VALUE ? -1 : minCount; + return memo[amount]; } - private int coinChange(int[] coins, int amount, int[] memo) { + // This approach times out due to overlapping subproblems + private int coinChangeRecursive(int[] coins, int amount) { if (amount < 0) { return -1; } if (amount == 0) { return 0; } - if (memo[amount - 1] != 0) { - return memo[amount - 1]; - } - int min = Integer.MAX_VALUE; + int minCount = Integer.MAX_VALUE; for (int coin : coins) { - int res = coinChange(coins, amount - coin, memo); - if (res >= 0 && res < min) { - min = 1 + res; + int count = coinChangeRecursive(coins, amount - coin); + if (count == -1) { + continue; } + minCount = Math.min(minCount, count); } - memo[amount - 1] = min == Integer.MAX_VALUE ? -1 : min; - return memo[amount - 1]; + return minCount == Integer.MAX_VALUE ? -1 : minCount; } } diff --git a/Medium/Combination Sum II.java b/Medium/Combination Sum II.java index 5b525f70..954373f5 100644 --- a/Medium/Combination Sum II.java +++ b/Medium/Combination Sum II.java @@ -1,26 +1,25 @@ class Solution { public List> combinationSum2(int[] candidates, int target) { - List> list = new ArrayList<>(); + List> result = new ArrayList<>(); Arrays.sort(candidates); - helper(candidates, 0, target, new ArrayList<>(), list); - return list; + helper(candidates, target, result, new ArrayList<>(), 0); + return result; } - private void helper(int[] candidates, int idx, int target, List temp, List> list) { - if (target == 0) { - list.add(new ArrayList<>(temp)); - return; - } - if (target < 0) { + private void helper(int[] candidates, int target, List> result, List currCombination, int idx) { + if (target <= 0) { + if (target == 0) { + result.add(new ArrayList<>(currCombination)); + } return; } for (int i = idx; i < candidates.length; i++) { - if (i > idx && candidates[i] == candidates[i - 1]) { + if (i > idx && candidates[i] == candidates[i - 1]) { continue; } - temp.add(candidates[i]); - helper(candidates, i + 1, target - candidates[i], temp, list); - temp.remove(temp.size() - 1); + currCombination.add(candidates[i]); + helper(candidates, target - candidates[i], result, currCombination, i + 1); + currCombination.remove(currCombination.size() - 1); } } } diff --git a/Medium/Combination Sum IV.java b/Medium/Combination Sum IV.java new file mode 100644 index 00000000..3a0eb51e --- /dev/null +++ b/Medium/Combination Sum IV.java @@ -0,0 +1,22 @@ +class Solution { + public int combinationSum4(int[] nums, int target) { + Integer[] dp = new Integer[target + 1]; + return helper(nums, target, dp); + } + + private int helper(int[] nums, int target, Integer[] dp) { + if (dp[target] != null) { + return dp[target]; + } + if (target == 0) { + return 1; + } + int count = 0; + for (int num : nums) { + if (target >= num) { + count += helper(nums, target - num, dp); + } + } + return dp[target] = count; + } +} diff --git a/Medium/Combination Sum.java b/Medium/Combination Sum.java index 6bd7aa66..6d9e8f77 100644 --- a/Medium/Combination Sum.java +++ b/Medium/Combination Sum.java @@ -1,24 +1,22 @@ class Solution { - public List> combinationSum(int[] candidates, int target) { - List> ans = new ArrayList<>(); - helper(candidates, 0, ans, new ArrayList<>(), target); - return ans; - } - - private void helper( - int[] candidates, int idx, List> ans, List list, int target - ) { - if (target == 0) { - ans.add(new ArrayList<>(list)); - return; + public List> combinationSum(int[] candidates, int target) { + List> result = new ArrayList<>(); + helper(candidates, target, new ArrayList<>(), result, 0); + return result; } - if (target < 0 || idx == candidates.length) { - return; + + private void helper(int[] candidates, int target, List combination, List> result, int idx) { + if (target < 0 || idx == candidates.length) { + return; + } + if (target == 0) { + result.add(combination); + return; + } + for (int i = idx; i < candidates.length; i++) { + combination.add(candidates[i]); + helper(candidates, target - candidates[i], new ArrayList<>(combination), result, i); + combination.remove(combination.size() - 1); + } } - for (int i = idx; i < candidates.length; i++) { - list.add(candidates[i]); - helper(candidates, i, ans, list, target - candidates[i]); - list.remove(list.size() - 1); - } - } } diff --git a/Medium/Combinations.java b/Medium/Combinations.java index f5d99e2b..425b44ff 100644 --- a/Medium/Combinations.java +++ b/Medium/Combinations.java @@ -1,26 +1,22 @@ class Solution { - public List> combine(int n, int k) { - List> ans = new ArrayList<>(); - List curr = new ArrayList<>(); - helper(ans, curr, new boolean[n], k, 0); - return ans; - } - - private void helper(List> ans, List curr, boolean[] visited, int k, int idx) { - if (curr.size() == k) { - ans.add(new ArrayList<>(curr)); + public List> combine(int n, int k) { + List> result = new ArrayList<>(); + helper(result, n, k, new ArrayList<>(), 1); + return result; } - else { - for (int i = idx; i < visited.length; i++) { - if (visited[i]) { - continue; + + private void helper(List> result, int n, int k, List curr, int currValue) { + if (curr.size() == k) { + result.add(new ArrayList<>(curr)); + return; + } + for (int i = currValue; i <= n; i++) { + if (!curr.isEmpty() && curr.get(curr.size() - 1) >= i) { + continue; + } + curr.add(i); + helper(result, n, k, curr, currValue + 1); + curr.remove(curr.size() - 1); } - curr.add(i + 1); - visited[i] = true; - helper(ans, curr, visited, k, i + 1); - curr.remove(curr.size() - 1); - visited[i] = false; - } } - } } diff --git a/Medium/Compare Version Numbers.java b/Medium/Compare Version Numbers.java index f41cecb0..b7b13684 100644 --- a/Medium/Compare Version Numbers.java +++ b/Medium/Compare Version Numbers.java @@ -1,29 +1,23 @@ class Solution { public int compareVersion(String version1, String version2) { - String[] versionSplit1 = version1.split("\\."); - String[] versionSplit2 = version2.split("\\."); - int idx1 = 0; - int idx2 = 0; - while (idx1 < versionSplit1.length || idx2 < versionSplit2.length) { - if (idx1 < versionSplit1.length && idx2 < versionSplit2.length) { - int ver1 = Integer.parseInt(versionSplit1[idx1++]); - int ver2 = Integer.parseInt(versionSplit2[idx2++]); - int c = ver1 - ver2; - if (c != 0) { - return c > 0 ? 1 : -1; - } + String[] splitOne = version1.split("\\."); + String[] splitTwo = version2.split("\\."); + int i = 0; + for (i = 0; i < Math.min(splitOne.length, splitTwo.length); i++) { + int diff = Integer.parseInt(splitOne[i]) - Integer.parseInt(splitTwo[i]); + if (diff == 0) { + continue; } - else if (idx1 < versionSplit1.length || idx2 == versionSplit2.length) { - int ver1 = Integer.parseInt(versionSplit1[idx1++]); - if (ver1 != 0) { - return 1; - } + return diff < 0 ? -1 : 1; + } + while (i < splitOne.length) { + if (Integer.parseInt(splitOne[i++]) > 0) { + return 1; } - else { - int ver2 = Integer.parseInt(versionSplit2[idx2++]); - if (ver2 != 0) { - return -1; - } + } + while (i < splitTwo.length) { + if (Integer.parseInt(splitTwo[i++]) > 0) { + return -1; } } return 0; diff --git a/Medium/Complex Number Multiplication.java b/Medium/Complex Number Multiplication.java index c206de72..f6d2500b 100644 --- a/Medium/Complex Number Multiplication.java +++ b/Medium/Complex Number Multiplication.java @@ -1,19 +1,63 @@ class Solution { - public String complexNumberMultiply(String a, String b) { - int realPart = 0; - int complexPart = 0; - int[] splitA = helper(a); - int[] splitB = helper(b); - realPart = splitA[0] * splitB[0] - splitA[1] * splitB[1]; - complexPart = splitA[0] * splitB[1] + splitA[1] * splitB[0]; - return realPart + "+" + complexPart + "i"; + public String complexNumberMultiply(String num1, String num2) { + ComplexNumber result = ComplexNumber.buildComplexNumber(num1).multiply(ComplexNumber.buildComplexNumber(num2)); + return result.toString(); } - private int[] helper(String s) { - String[] strs = s.split("\\+"); - int[] arr = new int[2]; - arr[0] = Integer.parseInt(strs[0]); - arr[1] = Integer.parseInt(strs[1].substring(0, strs[1].indexOf('i'))); - return arr; + + private static class ComplexNumber { + + private final int real; + private final int imaginary; + + private ComplexNumber(int real, int imaginary) { + this.real = real; + this.imaginary = imaginary; + } + + public static ComplexNumber buildComplexNumber(String s) { + int[] idx = {0}; + int realPart = parseRealPart(s, idx); + int imaginaryPart = parseImaginaryPart(s, idx); + return new ComplexNumber(realPart, imaginaryPart); + } + + public ComplexNumber multiply(ComplexNumber anotherNumber) { + int realPart = this.real * anotherNumber.real + (this.imaginary * anotherNumber.imaginary * -1); + int imaginaryPart = this.real * anotherNumber.imaginary + this.imaginary * anotherNumber.real; + return new ComplexNumber(realPart, imaginaryPart); + } + + public String toString() { + return this.real + "+" + this.imaginary + "i"; + } + + private static int parseRealPart(String s, int[] idx) { + int realSign = 1; + if (s.charAt(idx[0]) == '+' || s.charAt(idx[0]) == '-') { + realSign = s.charAt(idx[0]) == '-' ? -1 : 1; + idx[0]++; + } + int realNum = 0; + while (idx[0] < s.length() && Character.isDigit(s.charAt(idx[0]))) { + realNum = realNum * 10 + Character.getNumericValue(s.charAt(idx[0]++)); + } + realNum *= realSign; + idx[0]++; + return realNum; + } + + private static int parseImaginaryPart(String s, int[] idx) { + int imaginarySign = 1; + if (idx[0] < s.length() && (s.charAt(idx[0]) == '+' || s.charAt(idx[0]) == '-')) { + imaginarySign = s.charAt(idx[0]) == '-' ? -1 : 1; + idx[0]++; + } + int imaginaryNum = 0; + while (idx[0] < s.length() && s.charAt(idx[0]) != 'i') { + imaginaryNum = imaginaryNum * 10 + Character.getNumericValue(s.charAt(idx[0]++)); + } + return imaginarySign * imaginaryNum; + } } } diff --git a/Medium/Concatenation of Consecutive Binary Numbers.java b/Medium/Concatenation of Consecutive Binary Numbers.java new file mode 100644 index 00000000..fa27285f --- /dev/null +++ b/Medium/Concatenation of Consecutive Binary Numbers.java @@ -0,0 +1,14 @@ +class Solution { + public int concatenatedBinary(int n) { + final int MOD = 1000_000_007; + int length = 0; + long result = 0; + for (int i = 1; i <= n; i++) { + if (Math.pow(2, (int) (Math.log(i) / Math.log(2))) == i) { + length++; + } + result = ((result * (int) Math.pow(2, length)) + i) % MOD; + } + return (int) result; + } +} diff --git a/Medium/Connecting Cities With Minimum Cost.java b/Medium/Connecting Cities With Minimum Cost.java new file mode 100644 index 00000000..e1a90f09 --- /dev/null +++ b/Medium/Connecting Cities With Minimum Cost.java @@ -0,0 +1,59 @@ +class Solution { + public int minimumCost(int n, int[][] connections) { + Arrays.sort(connections, Comparator.comparingInt(a -> a[2])); + UnionFind unionFind = new UnionFind(n); + int totalCost = 0; + for (int[] connection : connections) { + int nodeOne = connection[0] - 1; + int nodeTwo = connection[1] - 1; + if (!unionFind.isConnected(nodeOne, nodeTwo)) { + totalCost += connection[2]; + unionFind.union(nodeOne, nodeTwo); + n--; + } + } + return n == 1 ? totalCost : -1; + } + + private static class UnionFind { + + private final int[] root; + private final int[] rank; + + public UnionFind(int size) { + this.root = new int[size]; + this.rank = new int[size]; + for (int i = 0; i < size; i++) { + this.root[i] = i; + this.rank[i] = 1; + } + } + + public void union(int nodeOne, int nodeTwo) { + int rootOne = find(nodeOne); + int rootTwo = find(nodeTwo); + if (rootOne != rootTwo) { + if (this.rank[rootOne] > this.rank[rootTwo]) { + this.root[rootTwo] = rootOne; + } else if (this.rank[rootOne] < this.rank[rootTwo]) { + this.root[rootOne] = rootTwo; + } else { + this.root[rootTwo] = rootOne; + this.rank[rootOne]++; + } + } + } + + + public int find(int node) { + if (node == root[node]) { + return node; + } + return root[node] = find(root[node]); + } + + public boolean isConnected(int nodeOne, int nodeTwo) { + return find(nodeOne) == find(nodeTwo); + } + } +} diff --git a/Medium/Construct Binary Search Tree from Preorder Traversal.java b/Medium/Construct Binary Search Tree from Preorder Traversal.java index 9361c50c..e2e044a8 100644 --- a/Medium/Construct Binary Search Tree from Preorder Traversal.java +++ b/Medium/Construct Binary Search Tree from Preorder Traversal.java @@ -4,25 +4,36 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - int idx; public TreeNode bstFromPreorder(int[] preorder) { - idx = 0; - return helper(preorder, Integer.MIN_VALUE, Integer.MAX_VALUE); - } - - private TreeNode helper(int[] preorder, int lower, int upper) { - if (idx == preorder.length || preorder[idx] < lower || preorder[idx] > upper) { + if (preorder.length == 0) { return null; } - int val = preorder[idx]; - idx++; - TreeNode root = new TreeNode(val); - root.left = helper(preorder, lower, val); - root.right = helper(preorder, val, upper); + TreeNode root = new TreeNode(preorder[0]); + Stack stack = new Stack<>(); + stack.push(root); + for (int i = 1; i < preorder.length; i++) { + TreeNode node = stack.peek(); + TreeNode child = new TreeNode(preorder[i]); + while (!stack.isEmpty() && stack.peek().val < child.val) { + node = stack.pop(); + } + if (node.val < child.val) { + node.right = child; + } else { + node.left = child; + } + stack.push(child); + } return root; } } diff --git a/Medium/Construct Binary Tree from Inorder and Postorder Traversal.java b/Medium/Construct Binary Tree from Inorder and Postorder Traversal.java index 9e69f9f5..ce312c11 100644 --- a/Medium/Construct Binary Tree from Inorder and Postorder Traversal.java +++ b/Medium/Construct Binary Tree from Inorder and Postorder Traversal.java @@ -14,24 +14,23 @@ * } */ class Solution { - int idx; public TreeNode buildTree(int[] inorder, int[] postorder) { Map map = new HashMap<>(); for (int i = 0; i < inorder.length; i++) { map.put(inorder[i], i); } - idx = postorder.length - 1; - return helper(inorder, postorder, 0, postorder.length - 1, map); + int[] postIdx = {postorder.length - 1}; + return helper(postorder, map, 0, inorder.length - 1, postIdx); } - private TreeNode helper(int[] inorder, int[] postorder, int start, int end, Map map) { - if (start > end) { + private TreeNode helper(int[] postorder, Map map, int leftIdx, int rightIdx, int[] postIdx) { + if (leftIdx > rightIdx) { return null; } - TreeNode node = new TreeNode(postorder[idx]); - int pos = map.get(postorder[idx--]); - node.right = helper(inorder, postorder, pos + 1, end, map); - node.left = helper(inorder, postorder, start, pos - 1, map); - return node; + TreeNode root = new TreeNode(postorder[postIdx[0]--]); + int index = map.get(root.val); + root.right = helper(postorder, map, index + 1, rightIdx, postIdx); + root.left = helper(postorder, map, leftIdx, index - 1, postIdx); + return root; } } diff --git a/Medium/Construct Binary Tree from Preorder and Inorder Traversal.java b/Medium/Construct Binary Tree from Preorder and Inorder Traversal.java new file mode 100644 index 00000000..1c2c1083 --- /dev/null +++ b/Medium/Construct Binary Tree from Preorder and Inorder Traversal.java @@ -0,0 +1,36 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public TreeNode buildTree(int[] preorder, int[] inorder) { + Map map = new HashMap<>(); + int[] preorderIndex = {0}; + for (int i = 0; i < inorder.length; i++) { + map.put(inorder[i], i); + } + return buildTree(preorder, 0, preorder.length - 1, map, preorderIndex); + } + + private TreeNode buildTree(int[] preorder, int left, int right, Map map, int[] preorderIndex) { + if (left > right) { + return null; + } + int rootVal = preorder[preorderIndex[0]++]; + TreeNode root = new TreeNode(rootVal); + root.left = buildTree(preorder, left, map.get(rootVal) - 1, map, preorderIndex); + root.right = buildTree(preorder, map.get(rootVal) + 1, right, map, preorderIndex); + return root; + } +} diff --git a/Medium/Construct Binary Tree from Preorder and Postorder Traversal.java b/Medium/Construct Binary Tree from Preorder and Postorder Traversal.java new file mode 100644 index 00000000..ca7aa35d --- /dev/null +++ b/Medium/Construct Binary Tree from Preorder and Postorder Traversal.java @@ -0,0 +1,40 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public TreeNode constructFromPrePost(int[] preorder, int[] postorder) { + int n = preorder.length; + Map postorderIndex = new HashMap<>(); + for (int i = 0; i < n; i++) { + postorderIndex.put(postorder[i], i); + } + return constructTree(0, n - 1, 0, preorder, postorderIndex); + } + + private TreeNode constructTree(int preStart, int preEnd, int postStart, int[] preorder, Map postorderIndex) { + if (preStart > preEnd) { + return null; + } + if (preStart == preEnd) { + return new TreeNode(preorder[preStart]); + } + int leftRoot = preorder[preStart + 1]; + int leftCount = postorderIndex.get(leftRoot) - postStart + 1; + TreeNode root = new TreeNode(preorder[preStart]); + root.left = constructTree(preStart + 1, preStart + leftCount, postStart, preorder, postorderIndex); + root.right = constructTree(preStart + leftCount + 1, preEnd, postStart + leftCount, preorder, postorderIndex); + return root; + } +} diff --git a/Medium/Construct K Palindrome Strings.java b/Medium/Construct K Palindrome Strings.java new file mode 100644 index 00000000..04f54681 --- /dev/null +++ b/Medium/Construct K Palindrome Strings.java @@ -0,0 +1,14 @@ +class Solution { + public boolean canConstruct(String s, int k) { + if (s.length() < k) { + return false; + } + int[] counter = new int[26]; + int numOfOddOccurence = 0; + for (char c : s.toCharArray()) { + counter[c - 'a']++; + numOfOddOccurence += counter[c - 'a'] % 2 == 0 ? -1 : 1; + } + return numOfOddOccurence <= k; + } +} diff --git a/Medium/Construct Smallest Number From DI String.java b/Medium/Construct Smallest Number From DI String.java new file mode 100644 index 00000000..64e39262 --- /dev/null +++ b/Medium/Construct Smallest Number From DI String.java @@ -0,0 +1,15 @@ +class Solution { + public String smallestNumber(String pattern) { + StringBuilder result = new StringBuilder(); + Stack stack = new Stack<>(); + for (int i = 0; i <= pattern.length(); i++) { + stack.push(i + 1); + if (i == pattern.length() || pattern.charAt(i) == 'I') { + while (!stack.isEmpty()) { + result.append(stack.pop()); + } + } + } + return result.toString(); + } +} diff --git a/Medium/Construct String With Repeat Limit.java b/Medium/Construct String With Repeat Limit.java new file mode 100644 index 00000000..4ac21148 --- /dev/null +++ b/Medium/Construct String With Repeat Limit.java @@ -0,0 +1,37 @@ +class Solution { + public String repeatLimitedString(String s, int repeatLimit) { + PriorityQueue pq = new PriorityQueue<>((o1, o2) -> o2 - o1); + for (char c : s.toCharArray()) { + pq.add(c); + } + StringBuilder sb = new StringBuilder(); + Stack stack = new Stack<>(); + int currentCharacterCount = 0; + char previousCharacter = pq.peek(); + while (!pq.isEmpty()) { + char currChar = pq.poll(); + if (currChar == previousCharacter) { + if (currentCharacterCount < repeatLimit) { + sb.append(currChar); + } else { + stack.add(currChar); + } + currentCharacterCount++; + } else { + if (stack.isEmpty()) { + sb.append(currChar); + previousCharacter = currChar; + currentCharacterCount = 1; + } else { + sb.append(currChar); + currentCharacterCount = 0; + while (!stack.isEmpty() && currentCharacterCount < repeatLimit) { + sb.append(stack.pop()); + currentCharacterCount++; + } + } + } + } + return sb.toString(); + } +} diff --git a/Medium/Container With Most Water.java b/Medium/Container With Most Water.java index fbdacebf..17fc1799 100644 --- a/Medium/Container With Most Water.java +++ b/Medium/Container With Most Water.java @@ -1,19 +1,18 @@ class Solution { public int maxArea(int[] height) { - int start = 0; - int end = height.length - 1; - int maxArea = 0; - while (start < end) { - int minHeight = Math.min(height[start], height[end]); - int dist = end - start; - maxArea = Math.max(maxArea, minHeight * dist); - if (height[start] > height[end]) { - end--; - } - else { - start++; + int maximumArea = 0; + int leftIdx = 0; + int rightIdx = height.length - 1; + while (leftIdx < rightIdx) { + int maxHeight = Math.min(height[leftIdx], height[rightIdx]); + int currArea = maxHeight * (rightIdx - leftIdx); + maximumArea = Math.max(currArea, maximumArea); + if (maxHeight == height[leftIdx]) { + leftIdx++; + } else { + rightIdx--; } } - return maxArea; + return maximumArea; } } diff --git a/Medium/Contiguous Array.java b/Medium/Contiguous Array.java index 554d8c65..204c9102 100644 --- a/Medium/Contiguous Array.java +++ b/Medium/Contiguous Array.java @@ -2,17 +2,16 @@ class Solution { public int findMaxLength(int[] nums) { Map map = new HashMap<>(); map.put(0, -1); - int maxLen = 0; + int maxLength = 0; int count = 0; for (int i = 0; i < nums.length; i++) { count += nums[i] == 0 ? -1 : 1; if (map.containsKey(count)) { - maxLen = Math.max(maxLen, i - map.get(count)); - } - else { + maxLength = Math.max(maxLength, i - map.get(count)); + } else { map.put(count, i); } } - return maxLen; + return maxLength; } } diff --git a/Medium/Continuous Subarray Sum.java b/Medium/Continuous Subarray Sum.java new file mode 100644 index 00000000..267857ab --- /dev/null +++ b/Medium/Continuous Subarray Sum.java @@ -0,0 +1,19 @@ +class Solution { + public boolean checkSubarraySum(int[] nums, int k) { + Map map = new HashMap<>(); + map.put(0, -1); + int currSum = 0; + for (int i = 0; i < nums.length; i++) { + currSum += nums[i]; + int rem = currSum % k; + if (map.containsKey(rem)) { + if (i - map.get(rem) >= 2) { + return true; + } + } else { + map.put(rem, i); + } + } + return false; + } +} diff --git a/Medium/Convert Binary Search Tree to Sorted Doubly Linked List.java b/Medium/Convert Binary Search Tree to Sorted Doubly Linked List.java index 838934c9..eaf92f02 100644 --- a/Medium/Convert Binary Search Tree to Sorted Doubly Linked List.java +++ b/Medium/Convert Binary Search Tree to Sorted Doubly Linked List.java @@ -20,27 +20,35 @@ public Node(int _val,Node _left,Node _right) { */ class Solution { - Node prev; public Node treeToDoublyList(Node root) { if (root == null) { return root; } - Node dummy = new Node(0); - prev = dummy; - helper(root); - prev.right = dummy.right; - dummy.right.left = prev; - return dummy.right; - } - - private void helper(Node root) { - if (root == null) { - return; + Stack stack = new Stack<>(); + while (root != null) { + stack.push(root); + root = root.left; + } + Node head = null; + Node prev = null; + while (!stack.isEmpty()) { + Node removed = stack.pop(); + Node rightNode = removed.right; + while (rightNode != null) { + stack.push(rightNode); + rightNode = rightNode.left; + } + if (head == null) { + head = removed; + } + if (prev != null) { + prev.right = removed; + } + removed.left = prev; + prev = removed; } - helper(root.left); - prev.right = root; - root.left = prev; - prev = root; - helper(root.right); + head.left = prev; + prev.right = head; + return head; } } diff --git a/Medium/Convert Sorted List to Binary Search Tree.java b/Medium/Convert Sorted List to Binary Search Tree.java index 5b49c0f3..c1258059 100644 --- a/Medium/Convert Sorted List to Binary Search Tree.java +++ b/Medium/Convert Sorted List to Binary Search Tree.java @@ -3,7 +3,9 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ /** @@ -12,35 +14,33 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - ListNode curr; - - public TreeNode sortedListToBST(ListNode head) { - curr = head; - return generate(count(head)); - } - - public int count(ListNode node) { - int n = 0; - while (node != null) { - node = node.next; - ++n; + public TreeNode sortedListToBST(ListNode head) { + List list = new ArrayList<>(); + while (head != null) { + list.add(head.val); + head = head.next; } - return n; + return helper(list, 0, list.size() - 1); } - public TreeNode generate(int n) { - if (n==0) return null; - - TreeNode node = new TreeNode(0); - node.left = generate(n/2); - node.val = curr.val; - curr = curr.next; - node.right = generate(n-(n/2)-1); - - return node; + private TreeNode helper(List list, int start, int end) { + if (start > end) { + return null; + } + int mid = (start + end) / 2; + TreeNode root = new TreeNode(list.get(mid)); + root.left = helper(list, start, mid - 1); + root.right = helper(list, mid + 1, end); + return root; } } diff --git a/Medium/Convert an Array Into a 2D Array With Conditions.java b/Medium/Convert an Array Into a 2D Array With Conditions.java new file mode 100644 index 00000000..c774bda6 --- /dev/null +++ b/Medium/Convert an Array Into a 2D Array With Conditions.java @@ -0,0 +1,25 @@ +class Solution { + public List> findMatrix(int[] nums) { + Map frequencyMap = new HashMap<>(); + for (int num : nums) { + frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1); + } + Queue queue = new LinkedList<>(); + queue.addAll(frequencyMap.keySet()); + List> result = new ArrayList<>(); + while (!queue.isEmpty()) { + int size = queue.size(); + List row = new ArrayList<>(); + while (size-- > 0) { + int removed = queue.remove(); + row.add(removed); + if (frequencyMap.get(removed) > 1) { + frequencyMap.put(removed, frequencyMap.get(removed) - 1); + queue.add(removed); + } + } + result.add(row); + } + return result; + } +} diff --git a/Medium/Copy List with Random Pointer.java b/Medium/Copy List with Random Pointer.java index f86d0155..071731bc 100644 --- a/Medium/Copy List with Random Pointer.java +++ b/Medium/Copy List with Random Pointer.java @@ -1,28 +1,58 @@ -/** - * Definition for singly-linked list with a random pointer. - * class RandomListNode { - * int label; - * RandomListNode next, random; - * RandomListNode(int x) { this.label = x; } - * }; - */ -public class Solution { - public RandomListNode copyRandomList(RandomListNode head) { - if (head == null) { - return null; - } - - RandomListNode ans = new RandomListNode(head.label); - RandomListNode curr = ans; - - while (head != null) { - curr.next = head.next == null ? null : new RandomListNode(head.next.label); - curr.random = head.random == null ? null : new RandomListNode(head.random.label); - - curr = curr.next; - head = head.next; - } - - return ans; +/* +// Definition for a Node. +class Node { + int val; + Node next; + Node random; + + public Node(int val) { + this.val = val; + this.next = null; + this.random = null; } } +*/ + +class Solution { + public Node copyRandomList(Node head) { + if (head == null) { + return head; + } + Node curr = head; + /* + List A->B->C + Expected outcome: A->A`->B->B`->C->C` + Where node marked with ` is copied node + */ + while (curr != null) { + Node newNode = new Node(curr.val); + newNode.next = curr.next; + curr.next = newNode; + curr = newNode.next; + } + curr = head; + /* + List A->A`->B->B`->C->C` + | | | (Random pointers) + C A B + Expected outcome: A->A`->B->B`->C->C` + | | | | | | + C C` A A` B B` + */ + while (curr != null) { + curr.next.random = curr.random != null ? curr.random.next : null; + curr = curr.next.next; + } + Node oldCurr = head; + Node newCurr = head.next; + Node newHead = head.next; // Retain a pointer to copied list's head + // Separate merged lists into original list & copied list. + while (oldCurr != null) { + oldCurr.next = oldCurr.next.next; + newCurr.next = newCurr.next != null ? newCurr.next.next : null; + oldCurr = oldCurr.next; + newCurr = newCurr.next; + } + return newHead; + } +} diff --git a/Medium/Count Collisions on a Road.java b/Medium/Count Collisions on a Road.java new file mode 100644 index 00000000..aa3d6358 --- /dev/null +++ b/Medium/Count Collisions on a Road.java @@ -0,0 +1,20 @@ +class Solution { + public int countCollisions(String directions) { + int idx = 0; + while (idx < directions.length() && directions.charAt(idx) == 'L') { + idx++; + } + int carsFromRight = 0; + int collisionCount = 0; + while (idx < directions.length()) { + if (directions.charAt(idx) == 'R') { + carsFromRight++; + } else { + collisionCount += directions.charAt(idx) == 'S' ? carsFromRight : carsFromRight + 1; + carsFromRight = 0; + } + idx++; + } + return collisionCount; + } +} diff --git a/Medium/Count Complete Substrings.java b/Medium/Count Complete Substrings.java new file mode 100644 index 00000000..995cf4b0 --- /dev/null +++ b/Medium/Count Complete Substrings.java @@ -0,0 +1,54 @@ +class Solution { + public int countCompleteSubstrings(String word, int k) { + int count = 0; + StringBuilder sb = new StringBuilder(); + int n = word.length(); + for (int i = 0; i < n; i++) { + sb.append(word.charAt(i)); + if (i < n - 1 && Math.abs(word.charAt(i) - word.charAt(i + 1)) > 2) { + count += calculateSubstrings(sb.toString(), k); + sb.setLength(0); + } + } + count += calculateSubstrings(sb.toString(), k); + return count; + } + + private int calculateSubstrings(String s, int k) { + int count = 0; + int n = s.length(); + for (int i = 1; i <= 26; i++) { + int len = k * i; + int[] freq = new int[26]; + if (len > n) { + break; + } + for (int j = 0; j < len; j++) { + freq[s.charAt(j) - 'a']++; + } + if (check(freq, i, k)) { + count++; + } + for (int j = len; j < n; j++) { + freq[s.charAt(j - len) - 'a']--; + freq[s.charAt(j) - 'a']++; + if (check(freq, i, k)) { + count++; + } + } + } + return count; + } + + private boolean check(int[] freq, int i, int k) { + for (int value : freq) { + if (value == 0) { + continue; + } + if (value != k) { + return false; + } + } + return true; + } +} diff --git a/Medium/Count Complete Tree Nodes.java b/Medium/Count Complete Tree Nodes.java index 8c4bd90f..822c178d 100644 --- a/Medium/Count Complete Tree Nodes.java +++ b/Medium/Count Complete Tree Nodes.java @@ -4,57 +4,35 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public int countNodes(TreeNode root) { - if (root == null) { - return 0; + public int countNodes(TreeNode root) { + int leftDepth = getDepth(root, -1); + int rightDepth = getDepth(root, 1); + if (leftDepth == rightDepth) { + return (1 << leftDepth) - 1; + } + return 1 + countNodes(root.left) + countNodes(root.right); } - int d = getDepth(root); - if (d == 0) { - return 1; + + private int getDepth(TreeNode root, int dir) { + int depth = 0; + while (root != null) { + depth++; + if (dir == -1) { + root = root.left; + } else { + root = root.right; + } + } + return depth; } - int start = 0; - int end = (int) Math.pow(2, d) - 1; - int mid; - while (start <= end) { - mid = start + (end - start) / 2; - if (exists(mid, d, root)) { - start = mid + 1; - } - else { - end = mid - 1; - } - } - return (int) Math.pow(2, d) - 1 + start; - } - - private int getDepth(TreeNode node) { - int d = 0; - while (node.left != null) { - node = node.left; - d++; - } - return d; - } - - private boolean exists(int idx, int d, TreeNode root) { - int left = 0; - int right = (int) Math.pow(2, d) - 1; - int mid; - for(int i = 0; i < d; ++i) { - mid = left + (right - left) / 2; - if (idx <= mid) { - root = root.left; - right = mid; - } - else { - root = root.right; - left = mid + 1; - } - } - return root != null; - } } diff --git a/Medium/Count Days Without Meetings.java b/Medium/Count Days Without Meetings.java new file mode 100644 index 00000000..1630e6df --- /dev/null +++ b/Medium/Count Days Without Meetings.java @@ -0,0 +1,24 @@ +class Solution { + public int countDays(int days, int[][] meetings) { + Arrays.sort(meetings, (o1, o2) -> { + int c = Integer.compare(o1[0], o2[0]); + if (c != 0) { + return c; + } + return Integer.compare(o2[1], o1[1]); + }); + int meetingDays = 0; + int idx = 0; + while (idx < meetings.length) { + int start = meetings[idx][0]; + int end = meetings[idx][1]; + idx++; + while (idx < meetings.length && meetings[idx][0] <= end) { + end = Math.max(end, meetings[idx][1]); + idx++; + } + meetingDays += (end - start + 1); + } + return days - meetingDays; + } +} diff --git a/Medium/Count Good Nodes in Binary Tree.java b/Medium/Count Good Nodes in Binary Tree.java index e5f87685..d3888f9d 100644 --- a/Medium/Count Good Nodes in Binary Tree.java +++ b/Medium/Count Good Nodes in Binary Tree.java @@ -16,18 +16,50 @@ class Solution { public int goodNodes(TreeNode root) { int[] count = {0}; - helper(root, root.val, count); + getGoodNodesCountRecursive(root, Integer.MIN_VALUE, count); return count[0]; } - private void helper(TreeNode root, int currMax, int[] count) { + private void getGoodNodesCountRecursive(TreeNode root, int currMax, int[] count) { if (root == null) { return; } if (root.val >= currMax) { count[0]++; } - helper(root.left, Math.max(currMax, root.val), count); - helper(root.right, Math.max(currMax, root.val), count); + getGoodNodesCountRecursive(root.left, Math.max(currMax, root.val), count); + getGoodNodesCountRecursive(root.right, Math.max(currMax, root.val), count); + } + + private int getGoodNodesCountNonRecursive(TreeNode root) { + if (root == null) { + return 0; + } + int count = 0; + Queue queue = new LinkedList<>(); + queue.add(new TreePair(root, Integer.MIN_VALUE)); + while (!queue.isEmpty()) { + TreePair removed = queue.remove(); + if (removed.node.val >= removed.currMax) { + count++; + } + if (removed.node.left != null) { + queue.add(new TreePair(removed.node.left, Math.max(removed.node.val, removed.currMax))); + } + if (removed.node.right != null) { + queue.add(new TreePair(removed.node.right, Math.max(removed.node.val, removed.currMax))); + } + } + return count; + } + + class TreePair { + int currMax; + TreeNode node; + + public TreePair(TreeNode node, int currMax) { + this.currMax = currMax; + this.node = node; + } } } diff --git a/Medium/Count Mentions Per User.java b/Medium/Count Mentions Per User.java new file mode 100644 index 00000000..7fa42668 --- /dev/null +++ b/Medium/Count Mentions Per User.java @@ -0,0 +1,61 @@ +class Solution { + public int[] countMentions(int numberOfUsers, List> eventLog) { + List events = eventLog.stream() + .map(Event::buildEvent) + .sorted() + .collect(Collectors.toList()); + Map offlineUsers = new HashMap<>(); + int[] mentions = new int[numberOfUsers]; + for (Event event : events) { + if (event.message().equals("OFFLINE")) { + offlineUsers.put(Integer.parseInt(event.mentionString()), event.timestamp()); + } else { + int timestamp = event.timestamp(); + List onlineUsers = offlineUsers.entrySet() + .stream() + .filter(t -> timestamp - t.getValue() >= 60) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + onlineUsers.forEach(offlineUsers::remove); + String mentionString = event.mentionString(); + if (mentionString.equals("ALL")) { + for (int i = 0; i < numberOfUsers; i++) { + mentions[i]++; + } + } else if (mentionString.equals("HERE")) { + for (int i = 0; i < numberOfUsers; i++) { + if (!offlineUsers.containsKey(i)) { + mentions[i]++; + } + } + } else { + String[] usersMentioned = mentionString.split(" "); + for (String user : usersMentioned) { + int userId = Integer.parseInt(user.substring(2)); + mentions[userId]++; + } + } + } + } + return mentions; + } + + private record Event(String message, int timestamp, String mentionString) implements Comparable { + + public static Event buildEvent(List event) { + String message = event.get(0); + int timestamp = Integer.parseInt(event.get(1)); + String mentionString = event.get(2); + return new Event(message, timestamp, mentionString); + } + + @Override + public int compareTo(Event o) { + int c = this.timestamp - o.timestamp; + if (c != 0) { + return c; + } + return o.message().compareTo(this.message()); + } + } +} diff --git a/Medium/Count Nodes Equal to Average of Subtree.java b/Medium/Count Nodes Equal to Average of Subtree.java new file mode 100644 index 00000000..5a6d2d75 --- /dev/null +++ b/Medium/Count Nodes Equal to Average of Subtree.java @@ -0,0 +1,36 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public int averageOfSubtree(TreeNode root) { + int[] result = {0}; + recurse(root, result); + return result[0]; + } + + private int[] recurse(TreeNode root, int[] result) { + if (root == null) { + return new int[]{0, 0}; + } + int[] left = recurse(root.left, result); + int[] right = recurse(root.right, result); + int sum = left[0] + right[0] + root.val; + int count = left[1] + right[1] + 1; + if (count != 0 && sum / count == root.val) { + result[0]++; + } + return new int[]{sum, count}; + } +} diff --git a/Medium/Count Nodes Equal to Sum of Descendants.java b/Medium/Count Nodes Equal to Sum of Descendants.java new file mode 100644 index 00000000..85597629 --- /dev/null +++ b/Medium/Count Nodes Equal to Sum of Descendants.java @@ -0,0 +1,34 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public int equalToDescendants(TreeNode root) { + int[] count = {0}; + helper(root, count); + return count[0]; + } + + private int helper(TreeNode root, int[] count) { + if (root == null) { + return 0; + } + int leftSum = helper(root.left, count); + int rightSum = helper(root.right, count); + if (root.val == leftSum + rightSum) { + count[0]++; + } + return root.val + leftSum + rightSum; + } +} diff --git a/Medium/Count Number of Bad Pairs.java b/Medium/Count Number of Bad Pairs.java new file mode 100644 index 00000000..e1002897 --- /dev/null +++ b/Medium/Count Number of Bad Pairs.java @@ -0,0 +1,12 @@ +class Solution { + public long countBadPairs(int[] nums) { + long result = 0; + Map map = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + int prevCount = map.getOrDefault(i - nums[i], 0); + result += i - prevCount; + map.put(i - nums[i], prevCount + 1); + } + return result; + } +} diff --git a/Medium/Count Number of Distinct Integers After Reverse Operations.java b/Medium/Count Number of Distinct Integers After Reverse Operations.java new file mode 100644 index 00000000..ecf51e81 --- /dev/null +++ b/Medium/Count Number of Distinct Integers After Reverse Operations.java @@ -0,0 +1,19 @@ +class Solution { + public int countDistinctIntegers(int[] nums) { + Set set = new HashSet<>(); + for (int num : nums) { + set.add(num); + set.add(reverse(num)); + } + return set.size(); + } + + private int reverse(int num) { + int reversed = 0; + while (num > 0) { + reversed = reversed * 10 + num % 10; + num /= 10; + } + return reversed; + } +} diff --git a/Medium/Count Number of Homogenous Substrings.java b/Medium/Count Number of Homogenous Substrings.java new file mode 100644 index 00000000..4a543690 --- /dev/null +++ b/Medium/Count Number of Homogenous Substrings.java @@ -0,0 +1,18 @@ +class Solution { + + private static final int MOD = 1_000_000_007; + + public int countHomogenous(String s) { + int result = 0; + int streak = 0; + for (int i = 0; i < s.length(); i++) { + if (i == 0 || s.charAt(i) == s.charAt(i - 1)) { + streak++; + } else { + streak = 1; + } + result = (result + streak) % MOD; + } + return result; + } +} diff --git a/Medium/Count Number of Maximum Bitwise-OR Subsets.java b/Medium/Count Number of Maximum Bitwise-OR Subsets.java new file mode 100644 index 00000000..973e1818 --- /dev/null +++ b/Medium/Count Number of Maximum Bitwise-OR Subsets.java @@ -0,0 +1,23 @@ +class Solution { + public int countMaxOrSubsets(int[] nums) { + int n = nums.length; + int maxValue = 0; + for (int num : nums) { + maxValue |= num; + } + Integer[][] dp = new Integer[n][maxValue + 1]; + return countMaxOrSubsets(nums, 0, 0, maxValue, dp); + } + + private int countMaxOrSubsets(int[] nums, int idx, int current, int maxValue, Integer[][] dp) { + if (idx == nums.length) { + return (current == maxValue) ? 1 : 0; + } + if (dp[idx][current] != null) { + return dp[idx][current]; + } + int countWithout = countMaxOrSubsets(nums, idx + 1, current, maxValue, dp); + int countWith = countMaxOrSubsets(nums, idx + 1, current | nums[idx], maxValue, dp); + return dp[idx][current] = countWith + countWithout; + } +} diff --git a/Medium/Count Number of Nice Subarrays.java b/Medium/Count Number of Nice Subarrays.java new file mode 100644 index 00000000..e2648bd3 --- /dev/null +++ b/Medium/Count Number of Nice Subarrays.java @@ -0,0 +1,14 @@ +class Solution { + public int numberOfSubarrays(int[] nums, int k) { + int sum = 0; + int count = 0; + Map map = new HashMap<>(); + map.put(sum, 1); + for (int i = 0; i < nums.length; i++) { + sum += nums[i] % 2; + count += map.getOrDefault(sum - k, 0); + map.put(sum, map.getOrDefault(sum, 0) + 1); + } + return count; + } +} diff --git a/Medium/Count Servers That Communicate.java b/Medium/Count Servers That Communicate.java index 81a2c8ff..34de8d30 100644 --- a/Medium/Count Servers That Communicate.java +++ b/Medium/Count Servers That Communicate.java @@ -1,31 +1,25 @@ class Solution { - public int countServers(int[][] grid) { - if (grid.length == 0 || grid[0].length == 0) { - return 0; + public int countServers(int[][] grid) { + int m = grid.length; + int n = grid[0].length; + int[] rowCount = new int[m]; + int[] colCount = new int[n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 1) { + rowCount[i]++; + colCount[j]++; } - int numRows = grid.length; - int numCols = grid[0].length; - int[] rowCount = new int[numRows]; - int[] colCount = new int[numCols]; - int numOfServers = 0; - for (int i = 0; i < numRows; i++) { - for (int j = 0; j < numCols; j++) { - if (grid[i][j] == 1) { - numOfServers++; - rowCount[i]++; - colCount[j]++; - } - } - } - for (int i = 0; i < numRows; i++) { - for (int j = 0; j < numCols; j++) { - if (grid[i][j] == 1) { - if (rowCount[i] == 1 && colCount[j] == 1) { - numOfServers--; - } - } - } + } + } + int connectedServerCount = 0; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 1 && (rowCount[i] > 1 || colCount[j] > 1)) { + connectedServerCount++; } - return numOfServers; + } } + return connectedServerCount; + } } diff --git a/Medium/Count Sorted Vowel Strings.java b/Medium/Count Sorted Vowel Strings.java new file mode 100644 index 00000000..757bf96e --- /dev/null +++ b/Medium/Count Sorted Vowel Strings.java @@ -0,0 +1,19 @@ +class Solution { + public int countVowelStrings(int n) { + Integer[][] memo = new Integer[n + 1][5]; + return topDownDP(n, 0, memo); + } + + private int topDownDP(int n, int idx, Integer[][] memo) { + if (n == 0) { + return 1; + } else if (idx == 5) { + return 0; + } else if (memo[n][idx] != null) { + return memo[n][idx]; + } + int numOfPermutations = topDownDP(n, idx + 1, memo); + numOfPermutations += topDownDP(n - 1, idx, memo); + return memo[n][idx] = numOfPermutations; + } +} diff --git a/Medium/Count Sub Islands.java b/Medium/Count Sub Islands.java new file mode 100644 index 00000000..adee5af9 --- /dev/null +++ b/Medium/Count Sub Islands.java @@ -0,0 +1,42 @@ +class Solution { + private final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + + public int countSubIslands(int[][] grid1, int[][] grid2) { + int numRows = grid1.length; + int numCols = grid1[0].length; + int subIslandCount = 0; + boolean[][] visited = new boolean[numRows][numCols]; + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numCols; j++) { + if (!visited[i][j] && grid2[i][j] == 1) { + Queue queue = new LinkedList<>(); + queue.add(new int[]{i, j}); + boolean isSubisland = true; + while (!queue.isEmpty()) { + int[] removed = queue.remove(); + int x = removed[0]; + int y = removed[1]; + if (visited[x][y]) { + continue; + } + if (grid1[x][y] != 1) { + isSubisland = false; + } + visited[x][y] = true; + for (int[] dir : DIRS) { + int newX = x + dir[0]; + int newY = y + dir[1]; + if (newX >= 0 && newY >= 0 && newX < numRows && newY < numCols && !visited[newX][newY] && grid2[newX][newY] == 1) { + queue.add(new int[]{newX, newY}); + } + } + } + if (isSubisland) { + subIslandCount++; + } + } + } + } + return subIslandCount; + } +} diff --git a/Medium/Count Subarrays Where Max Element Appears at Least K Times.java b/Medium/Count Subarrays Where Max Element Appears at Least K Times.java new file mode 100644 index 00000000..d917693d --- /dev/null +++ b/Medium/Count Subarrays Where Max Element Appears at Least K Times.java @@ -0,0 +1,24 @@ +class Solution { + public long countSubarrays(int[] nums, int k) { + int maxElement = 0; + for (int num : nums) { + maxElement = Math.max(maxElement, num); + } + long result = 0; + int start = 0; + int maxElementsInWindow = 0; + for (int end = 0; end < nums.length; end++) { + if (nums[end] == maxElement) { + maxElementsInWindow++; + } + while (k == maxElementsInWindow) { + if (nums[start] == maxElement) { + maxElementsInWindow--; + } + start++; + } + result += start; + } + return result; + } +} diff --git a/Medium/Count Substrings Without Repeating Character.java b/Medium/Count Substrings Without Repeating Character.java new file mode 100644 index 00000000..6ffcf7cd --- /dev/null +++ b/Medium/Count Substrings Without Repeating Character.java @@ -0,0 +1,19 @@ +class Solution { + public int numberOfSpecialSubstrings(String s) { + int start = 0; + int end = 0; + int n = s.length(); + int result = 0; + Map map = new HashMap<>(); + while (end < n) { + map.put(s.charAt(end), map.getOrDefault(s.charAt(end), 0) + 1); + while (start < end && map.get(s.charAt(end)) > 1) { + map.put(s.charAt(start), map.get(s.charAt(start)) - 1); + start++; + } + end++; + result += end - start; + } + return result; + } +} diff --git a/Medium/Count Total Number of Colored Cells.java b/Medium/Count Total Number of Colored Cells.java new file mode 100644 index 00000000..81c10a8c --- /dev/null +++ b/Medium/Count Total Number of Colored Cells.java @@ -0,0 +1,11 @@ +class Solution { + public long coloredCells(int n) { + long count = 1; + int increment = 4; + while (n-- > 1) { + count += increment; + increment += 4; + } + return count; + } +} diff --git a/Medium/Count Univalue Subtrees.java b/Medium/Count Univalue Subtrees.java index 2eae480a..73ac6599 100644 --- a/Medium/Count Univalue Subtrees.java +++ b/Medium/Count Univalue Subtrees.java @@ -15,27 +15,22 @@ */ class Solution { public int countUnivalSubtrees(TreeNode root) { + if (root == null) { + return 0; + } int[] count = {0}; - helper(root, count); + helper(root, count, root.val); return count[0]; } - private boolean helper(TreeNode root, int[] count) { + private boolean helper(TreeNode root, int[] count, int val) { if (root == null) { return true; } - boolean leftVal = helper(root.left, count); - boolean rightVal = helper(root.right, count); - if (leftVal && rightVal) { - if ( - (root.left != null && root.left.val != root.val) || - (root.right != null && root.right.val != root.val) - ) { - return false; - } - count[0]++; - return true; + if (!helper(root.left, count, root.val) | !helper(root.right, count, root.val)) { + return false; } - return false; + count[0]++; + return root.val == val; } } diff --git a/Medium/Count Unreachable Pairs of Nodes in an Undirected Graph.java b/Medium/Count Unreachable Pairs of Nodes in an Undirected Graph.java new file mode 100644 index 00000000..4b927bce --- /dev/null +++ b/Medium/Count Unreachable Pairs of Nodes in an Undirected Graph.java @@ -0,0 +1,36 @@ +class Solution { + public long countPairs(int n, int[][] edges) { + Map> graph = new HashMap<>(); + for (int[] edge : edges) { + graph.computeIfAbsent(edge[0], k -> new HashSet<>()).add(edge[1]); + graph.computeIfAbsent(edge[1], k -> new HashSet<>()).add(edge[0]); + } + boolean[] visited = new boolean[n]; + long unreachableNodeCount = (((long) n) * (n - 1)) / 2; + for (int i = 0; i < n; i++) { + if (!visited[i]) { + long reachCount = traverseHelper(i, graph, visited); + unreachableNodeCount -= (reachCount * (reachCount - 1)) / 2; + } + } + return unreachableNodeCount; + } + + private long traverseHelper(int node, Map> graph, boolean[] visited) { + Queue queue = new LinkedList<>(); + long count = 0; + queue.add(node); + visited[node] = true; + while (!queue.isEmpty()) { + int removed = queue.remove(); + count++; + for (Integer conn : graph.getOrDefault(removed, new HashSet<>())) { + if (!visited[conn]) { + visited[conn] = true; + queue.add(conn); + } + } + } + return count; + } +} diff --git a/Medium/Count Vowel Strings in Ranges.java b/Medium/Count Vowel Strings in Ranges.java new file mode 100644 index 00000000..8f836610 --- /dev/null +++ b/Medium/Count Vowel Strings in Ranges.java @@ -0,0 +1,26 @@ +class Solution { + + public int[] vowelStrings(String[] words, int[][] queries) { + int[] counter = new int[words.length]; + int currCounter = 0; + for (int i = 0; i < words.length; i++) { + String word = words[i]; + if (isVowel(word.charAt(0)) && isVowel(word.charAt(word.length() - 1))) { + currCounter++; + } + counter[i] = currCounter; + } + int[] result = new int[queries.length]; + for (int i = 0; i < queries.length; i++) { + int left = queries[i][0]; + int right = queries[i][1]; + result[i] = counter[right]; + result[i] -= left == 0 ? 0 : counter[left - 1]; + } + return result; + } + + private static boolean isVowel(char c) { + return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'; + } +} diff --git a/Medium/Count Ways To Build Good Strings.java b/Medium/Count Ways To Build Good Strings.java new file mode 100644 index 00000000..16991f0c --- /dev/null +++ b/Medium/Count Ways To Build Good Strings.java @@ -0,0 +1,23 @@ +class Solution { + + private static final int MOD = 1000_000_007; + + public int countGoodStrings(int low, int high, int zero, int one) { + int[] dp = new int[high + 1]; + dp[0] = 1; + for (int i = 1; i <= high; i++) { + if (i >= zero) { + dp[i] += dp[i - zero]; + } + if (i >= one) { + dp[i] += dp[i - one]; + } + dp[i] %= MOD; + } + int result = 0; + for (int i = low; i <= high; i++) { + result = (result + dp[i]) % MOD; + } + return result; + } +} diff --git a/Medium/Count and Say.java b/Medium/Count and Say.java new file mode 100644 index 00000000..a32318be --- /dev/null +++ b/Medium/Count and Say.java @@ -0,0 +1,19 @@ +class Solution { + public String countAndSay(int n) { + String s = "1"; + for (int i = 1; i < n; i++) { + StringBuilder sb = new StringBuilder(); + for (int j = 1, count = 1; j <= s.length(); j++) { + if (j == s.length() || s.charAt(j - 1) != s.charAt(j)) { + sb.append(count); + sb.append(s.charAt(j - 1)); + count = 1; + } else { + count++; + } + } + s = sb.toString(); + } + return s; + } +} diff --git a/Medium/Count the Number of Complete Components.java b/Medium/Count the Number of Complete Components.java new file mode 100644 index 00000000..d198b0b2 --- /dev/null +++ b/Medium/Count the Number of Complete Components.java @@ -0,0 +1,38 @@ +class Solution { + public int countCompleteComponents(int n, int[][] edges) { + Map> graph = new HashMap<>(); + for (int[] edge : edges) { + int nodeOne = edge[0]; + int nodeTwo = edge[1]; + graph.computeIfAbsent(nodeOne, k -> new HashSet<>()).add(nodeTwo); + graph.computeIfAbsent(nodeTwo, k -> new HashSet<>()).add(nodeOne); + } + int count = 0; + Set visited = new HashSet<>(); + for (int i = 0; i < n; i++) { + if (visited.add(i)) { + int[] componentInfo = new int[2]; + dfs(i, graph, visited, componentInfo); + if (componentInfo[0] * (componentInfo[0] - 1) == componentInfo[1]) { + count++; + } + } + } + return count; + } + + private void dfs( + int node, + Map> graph, + Set visited, + int[] componentInfo) { + componentInfo[0]++; + Set connections = graph.getOrDefault(node, new HashSet<>()); + componentInfo[1] += connections.size(); + for (Integer conn : connections) { + if (visited.add(conn)) { + dfs(conn, graph, visited, componentInfo); + } + } + } +} diff --git a/Medium/Count the Number of Good Nodes.java b/Medium/Count the Number of Good Nodes.java new file mode 100644 index 00000000..d100513d --- /dev/null +++ b/Medium/Count the Number of Good Nodes.java @@ -0,0 +1,34 @@ +class Solution { + public int countGoodNodes(int[][] edges) { + Map> map = new HashMap<>(); + for (int[] edge : edges) { + map.computeIfAbsent(edge[0], k -> new HashSet<>()).add(edge[1]); + map.computeIfAbsent(edge[1], k -> new HashSet<>()).add(edge[0]); + } + int[] result = {0}; + recurse(map, result, 0, -1); + return result[0]; + } + + private int recurse(Map> map, int[] result, int node, int prevNode) { + int count = -1; + int total = 1; + boolean flag = true; + for (Integer conn : map.getOrDefault(node, new HashSet<>())) { + if (conn == prevNode) { + continue; + } + int temp = recurse(map, result, conn, node); + total += temp; + if (count == -1) { + count = temp; + } else if (count != temp) { + flag = false; + } + } + if (flag) { + result[0]++; + } + return total; + } +} diff --git a/Medium/Counting Bits.java b/Medium/Counting Bits.java deleted file mode 100644 index ee39c468..00000000 --- a/Medium/Counting Bits.java +++ /dev/null @@ -1,13 +0,0 @@ -class Solution { - public int[] countBits(int num) { - int result[] = new int[num + 1]; - int offset = 1; - for (int index = 1; index < num + 1; ++index){ - if (offset * 2 == index){ - offset *= 2; - } - result[index] = result[index - offset] + 1; - } - return result; - } -} diff --git a/Medium/Course Schedule II.java b/Medium/Course Schedule II.java index 4dc8b847..ce957faf 100644 --- a/Medium/Course Schedule II.java +++ b/Medium/Course Schedule II.java @@ -1,29 +1,32 @@ class Solution { - public int[] findOrder(int numCourses, int[][] prerequisites) { - Map> map = new HashMap<>(); - int[] prereqCount = new int[numCourses]; - for (int[] prerequisite : prerequisites) { - prereqCount[prerequisite[0]]++; - map.computeIfAbsent(prerequisite[1], k -> new ArrayList<>()).add(prerequisite[0]); - } - Queue queue = new LinkedList<>(); - for (int i = 0; i < numCourses; i++) { - if (prereqCount[i] == 0) { - queue.add(i); - } - } - int[] ans = new int[numCourses]; - int idx = 0; - while (!queue.isEmpty()) { - int removed = queue.remove(); - for (Integer dependentCourse : map.getOrDefault(removed, new ArrayList<>())) { - prereqCount[dependentCourse]--; - if (prereqCount[dependentCourse] == 0) { - queue.add(dependentCourse); + public int[] findOrder(int numCourses, int[][] prerequisites) { + Map> map = new HashMap<>(); + int[] indegree = new int[numCourses]; + for (int[] prerequisite : prerequisites) { + int course = prerequisite[0]; + int dependency = prerequisite[1]; + map.computeIfAbsent(dependency, k -> new HashSet<>()).add(course); + indegree[course]++; + } + Queue queue = new LinkedList<>(); + int[] result = new int[numCourses]; + int resultIdx = 0; + Set taken = new HashSet<>(); + for (int i = 0; i < numCourses; i++) { + if (indegree[i] == 0) { + queue.add(i); + } + } + while (!queue.isEmpty()) { + int removed = queue.remove(); + result[resultIdx++] = removed; + for (Integer dependent : map.getOrDefault(removed, new HashSet<>())) { + indegree[dependent]--; + if (indegree[dependent] == 0) { + queue.add(dependent); + } + } } - } - ans[idx++] = removed; + return resultIdx == numCourses ? result : new int[0]; } - return idx == numCourses ? ans : new int[]{}; - } } diff --git a/Medium/Course Schedule.java b/Medium/Course Schedule.java index bea1a964..1f8c0693 100644 --- a/Medium/Course Schedule.java +++ b/Medium/Course Schedule.java @@ -1,29 +1,31 @@ class Solution { - public boolean canFinish(int numCourses, int[][] prerequisites) { - Map> map = new HashMap<>(); - int[] indegree = new int[numCourses]; - for (int[] prerequisite : prerequisites) { - map.computeIfAbsent(prerequisite[1], k -> new HashSet<>()).add(prerequisite[0]); - indegree[prerequisite[0]]++; - } - Queue queue = new LinkedList<>(); - Set taken = new HashSet<>(); - for (int i = 0; i < numCourses; i++) { - if (indegree[i] == 0) { - queue.add(i); - taken.add(i); - } - } - while (!queue.isEmpty()) { - int removed = queue.remove(); - for (Integer dependentCourse : map.getOrDefault(removed, new HashSet<>())) { - indegree[dependentCourse]--; - if (indegree[dependentCourse] == 0) { - taken.add(dependentCourse); - queue.add(dependentCourse); + public boolean canFinish(int numCourses, int[][] prerequisites) { + int[] indegree = new int[numCourses]; + Map> map = new HashMap<>(); + for (int[] prerequisite : prerequisites) { + int course = prerequisite[0]; + int prereq = prerequisite[1]; + indegree[course]++; + map.computeIfAbsent(prereq, k -> new HashSet<>()).add(course); + } + Queue queue = new LinkedList<>(); + Set visited = new HashSet<>(); + for (int i = 0; i < numCourses; i++) { + if (indegree[i] == 0) { + queue.add(i); + visited.add(i); + } + } + while (!queue.isEmpty()) { + int removed = queue.remove(); + for (Integer conn : map.getOrDefault(removed, new HashSet<>())) { + indegree[conn]--; + if (indegree[conn] == 0) { + queue.add(conn); + visited.add(conn); + } + } } - } + return visited.size() == numCourses; } - return taken.size() == numCourses; - } } diff --git a/Medium/Cousins in Binary Tree II.java b/Medium/Cousins in Binary Tree II.java new file mode 100644 index 00000000..ee1b4b21 --- /dev/null +++ b/Medium/Cousins in Binary Tree II.java @@ -0,0 +1,44 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public TreeNode replaceValueInTree(TreeNode root) { + Queue queue = new LinkedList<>(); + queue.add(root); + int prevLevelSum = root.val; + while (!queue.isEmpty()) { + int size = queue.size(); + int levelSum = 0; + for (int i = 0; i < size; i++) { + TreeNode node = queue.remove(); + node.val = prevLevelSum - node.val; + int siblingSum = (node.left != null ? node.left.val : 0) + + (node.right != null ? node.right.val : 0); + if (node.left != null) { + levelSum += node.left.val; + node.left.val = siblingSum; + queue.add(node.left); + } + if (node.right != null) { + levelSum += node.right.val; + node.right.val = siblingSum; + queue.add(node.right); + } + } + prevLevelSum = levelSum; + } + return root; + } +} diff --git a/Medium/Create Binary Tree From Descriptions.java b/Medium/Create Binary Tree From Descriptions.java new file mode 100644 index 00000000..bb04e8d2 --- /dev/null +++ b/Medium/Create Binary Tree From Descriptions.java @@ -0,0 +1,37 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public TreeNode createBinaryTree(int[][] descriptions) { + Map nodeMapping = new HashMap<>(); + Set childNodes = new HashSet<>(); + for (int[] description : descriptions) { + nodeMapping.putIfAbsent(description[0], new TreeNode(description[0])); + nodeMapping.putIfAbsent(description[1], new TreeNode(description[1])); + if (description[2] == 1) { + nodeMapping.get(description[0]).left = nodeMapping.get(description[1]); + } else { + nodeMapping.get(description[0]).right = nodeMapping.get(description[1]); + } + childNodes.add(description[1]); + } + for (Integer key : nodeMapping.keySet()) { + if (!childNodes.contains(key)) { + return nodeMapping.get(key); + } + } + return null; + } +} diff --git a/Medium/Custom Sort String.java b/Medium/Custom Sort String.java index 1fe011ce..ecdcb98d 100644 --- a/Medium/Custom Sort String.java +++ b/Medium/Custom Sort String.java @@ -1,24 +1,21 @@ class Solution { - public String customSortString(String S, String T) { - Set set = new HashSet<>(); - for (int i = 0; i < S.length(); i++) { - set.add(S.charAt(i)); + public String customSortString(String order, String s) { + Map frequency = new HashMap<>(); + for (char c : s.toCharArray()) { + frequency.put(c, frequency.getOrDefault(c, 0) + 1); } - Map map = new HashMap<>(); StringBuilder sb = new StringBuilder(); - for (char c : T.toCharArray()) { - if (set.contains(c)) { - map.put(c, map.getOrDefault(c, 0) + 1); - } - else { + for (char c : order.toCharArray()) { + int count = frequency.getOrDefault(c, 0); + while (count-- > 0) { sb.append(c); } + frequency.put(c, 0); } - for (int i = 0; i < S.length(); i++) { - char c = S.charAt(i); - int count = map.getOrDefault(c, 0); + for (Character key : frequency.keySet()) { + int count = frequency.getOrDefault(key, 0); while (count-- > 0) { - sb.append(c); + sb.append(key); } } return sb.toString(); diff --git a/Medium/Daily Temperatures.java b/Medium/Daily Temperatures.java index ce3bdca3..5189f7ee 100644 --- a/Medium/Daily Temperatures.java +++ b/Medium/Daily Temperatures.java @@ -1,14 +1,15 @@ class Solution { - public int[] dailyTemperatures(int[] T) { - Stack stack = new Stack<>(); - int[] ans = new int[T.length]; - for (int i = T.length - 1; i >= 0; i--) { - while (!stack.isEmpty() && T[stack.peek()] <= T[i]) { - stack.pop(); - } - ans[i] = stack.isEmpty() ? 0 : (stack.peek() - i); - stack.push(i); + public int[] dailyTemperatures(int[] temperatures) { + int n = temperatures.length; + int[] result = new int[n]; + Stack stack = new Stack<>(); + for (int i = n - 1; i >= 0; i--) { + while (!stack.isEmpty() && temperatures[i] >= temperatures[stack.peek()]) { + stack.pop(); + } + result[i] = stack.isEmpty() ? 0 : stack.peek() - i; + stack.push(i); + } + return result; } - return ans; - } } diff --git a/Medium/Decode String.java b/Medium/Decode String.java index 7381fd10..fb2f81de 100644 --- a/Medium/Decode String.java +++ b/Medium/Decode String.java @@ -1,39 +1,32 @@ class Solution { - public static String decodeString(String s) { - Stack count = new Stack<>(); - Stack str = new Stack<>(); - int i = 0; - str.push(""); - while(i < s.length()) { - if (s.charAt(i) >= '0' && s.charAt(i) <= '9') { - int start = i; - while (s.charAt(i+1) >= '0' && s.charAt(i+1) <= '9') { - i++; - } - count.push(Integer.parseInt(s.substring(start, i + 1))); - } - else if (s.charAt(i) == '[') { - str.push(""); - } - else if (s.charAt(i) == ']') { - String st = str.pop(); - StringBuilder sb = new StringBuilder(); - int n = count.pop(); - - for (int j = 0; j < n; j++) { - sb.append(st); - } - - str.push(str.pop() + sb.toString()); - } - else { - str.push(str.pop() + s.charAt(i)); - } - - i++; + public String decodeString(String s) { + Stack stack = new Stack<>(); + for (char c : s.toCharArray()) { + if (c == ']') { + StringBuilder sb = new StringBuilder(); + while (!stack.isEmpty() && stack.peek() != '[') { + sb.append(stack.pop()); } - - return str.pop(); + stack.pop(); + String temp = sb.toString(); + sb.setLength(0); + while (!stack.isEmpty() && Character.isDigit(stack.peek())) { + sb.append(stack.pop()); + } + int count = Integer.parseInt(sb.reverse().toString()); + while (count-- > 0) { + for (int i = temp.length() - 1; i >= 0; i--) { + stack.push(temp.charAt(i)); + } + } + } else { + stack.push(c); + } + } + StringBuilder sb = new StringBuilder(); + while (!stack.isEmpty()) { + sb.append(stack.pop()); } + return sb.reverse().toString(); + } } - diff --git a/Medium/Decode Ways.java b/Medium/Decode Ways.java index cbba3c77..a959c15a 100644 --- a/Medium/Decode Ways.java +++ b/Medium/Decode Ways.java @@ -1,58 +1,28 @@ class Solution { - int[] memo; - public int numDecodings(String s) { - if (s.length() == 0) { - return 0; - } - - memo = new int[s.length() + 1]; - Arrays.fill(memo, -1); - - return helperDp(0, s); + + public int numDecodings(String s) { + Map map = new HashMap<>(); + return helper(s, 0, map); + } + + private int helper(String s, int idx, Map map) { + if (map.containsKey(idx)) { + return map.get(idx); } - - private int helperDp(int idx, String s) { - if (memo[idx] > -1) { - return memo[idx]; - } - - int n = s.length(); - if (idx == n) { - return memo[idx] = 1; - } - - if (s.charAt(idx) == '0') { - return memo[idx] = 0; - } - - int temp = helperRecursive(idx + 1, s); - memo[idx + 1] = temp; - - if (idx < n - 1 && (s.charAt(idx) == '1' || (s.charAt(idx) == '2' && s.charAt(idx + 1) < '7'))) { - memo[idx + 2] = helperRecursive(idx + 2, s); - temp += memo[idx + 2]; - } - - return temp; + if (idx == s.length()) { + return 1; } - - private int helperRecursive(int idx, String s) { - int n = s.length(); - - if (idx == n) { - return 1; - } - - if (s.charAt(idx) == '0') { - return 0; - } - - int temp = helperRecursive(idx + 1, s); - - if (idx < n - 1 && (s.charAt(idx) == '1' || (s.charAt(idx) == '2' && s.charAt(idx + 1) < '7'))) { - temp += helperRecursive(idx + 2, s); - } - - return temp; + if (s.charAt(idx) == '0') { + return 0; } + if (idx == s.length() - 1) { + return 1; + } + int result = helper(s, idx + 1, map); + if (Integer.parseInt(s.substring(idx, idx + 2)) <= 26) { + result += helper(s, idx + 2, map); + } + map.put(idx, result); + return result; + } } diff --git a/Medium/Decoded String at Index.java b/Medium/Decoded String at Index.java new file mode 100644 index 00000000..a0c94968 --- /dev/null +++ b/Medium/Decoded String at Index.java @@ -0,0 +1,27 @@ +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--; + } + } + return ""; + } +} diff --git a/Medium/Deepest Leaves Sum.java b/Medium/Deepest Leaves Sum.java index 82138314..df67a081 100644 --- a/Medium/Deepest Leaves Sum.java +++ b/Medium/Deepest Leaves Sum.java @@ -4,29 +4,30 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - Map map; - int deepestLevel; public int deepestLeavesSum(TreeNode root) { - map = new HashMap<>(); - deepestLevel = 0; - helper(root, 0); - return map.get(deepestLevel); + Map map = new HashMap<>(); + helper(root, 0, map); + return map.getOrDefault( + map.keySet().stream().mapToInt(Integer::valueOf).max().orElse(0), 0 + ); } - private void helper(TreeNode root, int level) { + private void helper(TreeNode root, int currLevel, Map map) { if (root == null) { return; } - if (root.left == null && root.right == null) { - map.put(level, map.getOrDefault(level, 0) + root.val); - deepestLevel = Math.max(deepestLevel, level); - return; - } - helper(root.left, level + 1); - helper(root.right, level + 1); + map.put(currLevel, map.getOrDefault(currLevel, 0) + root.val); + helper(root.left, currLevel + 1, map); + helper(root.right, currLevel + 1, map); } } diff --git a/Medium/Delete Node in a BST.java b/Medium/Delete Node in a BST.java index 8502798f..becc3b24 100644 --- a/Medium/Delete Node in a BST.java +++ b/Medium/Delete Node in a BST.java @@ -18,25 +18,20 @@ public TreeNode deleteNode(TreeNode root, int key) { if (root == null) { return null; } - if (root.val > key) { - root.left = deleteNode(root.left, key); - } - else if (root.val < key) { + if (key > root.val) { root.right = deleteNode(root.right, key); - } - else { + } else if (key < root.val) { + root.left = deleteNode(root.left, key); + } else { if (root.left == null || root.right == null) { - TreeNode temp = root.left == null ? root.right : root.left; - return temp; - } - else { - TreeNode inorderSuccessor = root.right; - while (inorderSuccessor.left != null) { - inorderSuccessor = inorderSuccessor.left; - } - root.val = inorderSuccessor.val; - root.right = deleteNode(root.right, inorderSuccessor.val); + return root.left == null ? root.right : root.left; + } + TreeNode inorderSuccessor = root.right; + while (inorderSuccessor.left != null) { + inorderSuccessor = inorderSuccessor.left; } + root.val = inorderSuccessor.val; + root.right = deleteNode(root.right, inorderSuccessor.val); } return root; } diff --git a/Medium/Delete Nodes And Return Forest.java b/Medium/Delete Nodes And Return Forest.java index b65710bc..344770b5 100644 --- a/Medium/Delete Nodes And Return Forest.java +++ b/Medium/Delete Nodes And Return Forest.java @@ -4,46 +4,44 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public List delNodes(TreeNode root, int[] to_delete) { - List forest = new ArrayList<>(); - Set set = new HashSet<>(); - for (int num : to_delete) { - set.add(num); - } - helper(root, set, forest, null, 0); - return forest; - } - - private void helper(TreeNode root, Set set, List forest, TreeNode parent, int side) { - if (root == null) { - return; + public List delNodes(TreeNode root, int[] toDelete) { + Set set = new HashSet<>(); + for (int val : toDelete) { + set.add(val); + } + List result = new ArrayList<>(); + recurse(root, result, set, null); + return result; } - // Deletion - if (set.contains(root.val)) { - if (parent != null) { - // Decide which node we want to make null based on side - if (side == -1) { - parent.left = null; + + private void recurse(TreeNode root, List result, Set set, TreeNode parent) { + if (root == null) { + return; } - else { - parent.right = null; + if (set.contains(root.val)) { + if (parent != null && parent.left == root) { + parent.left = null; + } else if (parent != null && parent.right == root) { + parent.right = null; + } + recurse(root.left, result, set, null); + recurse(root.right, result, set, null); + return; } - } - // Call the recursive function for left & right with parent as null as we deleted the node - helper(root.left, set, forest, null, 0); - helper(root.right, set, forest, null, 0); - } - // No Deletion - else { - if (parent == null) { // Don't add if we have already added the parent and this is a child node - forest.add(root); - } - helper(root.left, set, forest, root, -1); - helper(root.right, set, forest, root, 1); + if (parent == null) { + result.add(root); + } + recurse(root.left, result, set, root); + recurse(root.right, result, set, root); } - } } diff --git a/Medium/Delete Nodes From Linked List Present in Array.java b/Medium/Delete Nodes From Linked List Present in Array.java new file mode 100644 index 00000000..ff184902 --- /dev/null +++ b/Medium/Delete Nodes From Linked List Present in Array.java @@ -0,0 +1,31 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode modifiedList(int[] nums, ListNode head) { + Set set = new HashSet<>(); + for (int num : nums) { + set.add(num); + } + while (head != null && set.contains(head.val)) { + head = head.next; + } + ListNode newHead = head; + ListNode curr = head; + while (curr.next != null) { + if (set.contains(curr.next.val)) { + curr.next = curr.next.next; + } else { + curr = curr.next; + } + } + return newHead; + } +} diff --git a/Medium/Delete Operation for Two Strings.java b/Medium/Delete Operation for Two Strings.java index 8e8f1ea5..f5e48340 100644 --- a/Medium/Delete Operation for Two Strings.java +++ b/Medium/Delete Operation for Two Strings.java @@ -1,25 +1,21 @@ class Solution { - public int minDistance(String word1, String word2) { - int[][] memo = new int[word1.length() + 1][word2.length() + 1]; - for (int i = 0; i <= word1.length(); i++) { - for (int j = 0; j <= word2.length(); j++) { - if (i == 0) { - memo[i][j] = j; - } - else if (j == 0) { - memo[i][j] = i; - } - else if (word1.charAt(i - 1) == word2.charAt(j - 1)) { - memo[i][j] = memo[i - 1][j - 1]; - } - else { - memo[i][j] = Math.min(Math.min(memo[i - 1][j - 1] + 2, memo[i - 1][j] + 1), - memo[i][j - 1] + 1); - } - } - } - - return memo[word1.length()][word2.length()]; + public int minDistance(String word1, String word2) { + int[][] dp = new int[word1.length() + 1][word2.length() + 1]; + return word1.length() + word2.length() - 2 * longestCommonSubsequence(word1, word2, word1.length(), word2.length(), dp); + } + + private int longestCommonSubsequence(String word1, String word2, int m, int n, int[][] dp) { + if (m == 0 || n == 0) { + return 0; } + if (dp[m][n] > 0) { + return dp[m][n]; + } + if (word1.charAt(m - 1) == word2.charAt(n - 1)) { + dp[m][n] = 1 + longestCommonSubsequence(word1, word2, m - 1, n - 1, dp); + } else { + dp[m][n] = Math.max(longestCommonSubsequence(word1, word2, m - 1, n, dp), longestCommonSubsequence(word1, word2, m, n - 1, dp)); + } + return dp[m][n]; + } } - diff --git a/Medium/Delete the Middle Node of a Linked List.java b/Medium/Delete the Middle Node of a Linked List.java new file mode 100644 index 00000000..1fe07371 --- /dev/null +++ b/Medium/Delete the Middle Node of a Linked List.java @@ -0,0 +1,25 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode deleteMiddle(ListNode head) { + if (head.next == null) { + return null; + } + ListNode slow = head; + ListNode fast = head.next.next; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + } + slow.next = slow.next.next; + return head; + } +} diff --git a/Medium/Design A Leaderboard.java b/Medium/Design A Leaderboard.java index 9a5ca751..8ae6740f 100644 --- a/Medium/Design A Leaderboard.java +++ b/Medium/Design A Leaderboard.java @@ -1,39 +1,43 @@ class Leaderboard { - Map scoreMap; - Map> playerMap; - public Leaderboard() { - scoreMap = new HashMap<>(); - playerMap = new TreeMap<>(Collections.reverseOrder()); - } - public void addScore(int playerId, int score) { - if (scoreMap.containsKey(playerId)) { - int prevScore = scoreMap.get(playerId); - playerMap.get(prevScore).remove(playerId); - } - scoreMap.put(playerId, scoreMap.getOrDefault(playerId, 0) + score); - playerMap.computeIfAbsent(scoreMap.get(playerId), k -> new HashSet<>()).add(playerId); - } + private Map playerToScoreMapping; + private Map> scoreToPlayerMapping; - public int top(int K) { - int sum = 0; - for (Integer key : playerMap.keySet()) { - int count = Math.min(K, playerMap.get(key).size()); - sum += key * count; - K -= count; - if (K == 0) { - break; - } - } - return sum; + public Leaderboard() { + this.playerToScoreMapping = new HashMap<>(); + this.scoreToPlayerMapping = new TreeMap<>(Collections.reverseOrder()); + } + + public void addScore(int playerId, int score) { + if (playerToScoreMapping.containsKey(playerId)) { + int previousScore = playerToScoreMapping.get(playerId); + if (scoreToPlayerMapping.getOrDefault(previousScore, new HashSet<>()).contains(playerId)) { + scoreToPlayerMapping.get(previousScore).remove(playerId); + } + score += previousScore; } + playerToScoreMapping.put(playerId, score); + scoreToPlayerMapping.computeIfAbsent(score, k -> new HashSet<>()).add(playerId); + } - public void reset(int playerId) { - int prevScore = scoreMap.get(playerId); - playerMap.get(prevScore).remove(playerId); - scoreMap.put(playerId, 0); - playerMap.computeIfAbsent(0, k -> new HashSet<>()).add(playerId); + public int top(int K) { + int totalScore = 0; + for (Integer currScore : scoreToPlayerMapping.keySet()) { + int totalPlayersWithScore = scoreToPlayerMapping.get(currScore).size(); + int playersRemaining = Math.min(K, totalPlayersWithScore); + totalScore += playersRemaining * currScore; + K -= playersRemaining; + if (K == 0) { + break; + } } + return totalScore; + } + + public void reset(int playerId) { + scoreToPlayerMapping.get(playerToScoreMapping.get(playerId)).remove(playerId); + playerToScoreMapping.put(playerId, 0); + } } /** diff --git a/Medium/Design Add and Search Words Data Structure.java b/Medium/Design Add and Search Words Data Structure.java new file mode 100644 index 00000000..17814eb0 --- /dev/null +++ b/Medium/Design Add and Search Words Data Structure.java @@ -0,0 +1,58 @@ +class WordDictionary { + + private final TrieNode root; + + public WordDictionary() { + this.root = new TrieNode(); + } + + public void addWord(String word) { + TrieNode curr = root; + for (char c : word.toCharArray()) { + if (!curr.children.containsKey(c)) { + curr.children.put(c, new TrieNode()); + } + curr = curr.children.get(c); + } + curr.isWord = true; + } + + public boolean search(String word) { + return searchHelper(word, 0, root); + } + + private boolean searchHelper(String word, int idx, TrieNode node) { + if (idx == word.length()) { + return node.isWord; + } + if (node.children.containsKey(word.charAt(idx))) { + return searchHelper(word, idx + 1, node.children.get(word.charAt(idx))); + } + if (word.charAt(idx) == '.') { + for (TrieNode child : node.children.values()) { + if (searchHelper(word, idx + 1, child)) { + return true; + } + } + } + return false; + } + + + static class TrieNode { + private final Map children; + private boolean isWord; + + public TrieNode() { + this.children = new HashMap<>(); + this.isWord = false; + } + } +} + +/** + * Your WordDictionary object will be instantiated and called as such: + * WordDictionary obj = new WordDictionary(); + * obj.addWord(word); + * boolean param_2 = obj.search(word); + */ diff --git a/Medium/Design Authentication Manager.java b/Medium/Design Authentication Manager.java new file mode 100644 index 00000000..93071b1d --- /dev/null +++ b/Medium/Design Authentication Manager.java @@ -0,0 +1,33 @@ +class AuthenticationManager { + + Map map; + int timeToLive; + + public AuthenticationManager(int timeToLive) { + map = new HashMap<>(); + this.timeToLive = timeToLive; + } + + public void generate(String tokenId, int currentTime) { + map.put(tokenId, currentTime); + } + + public void renew(String tokenId, int currentTime) { + if (map.containsKey(tokenId) && map.get(tokenId) + timeToLive > currentTime) { + map.put(tokenId, currentTime); + } + } + + public int countUnexpiredTokens(int currentTime) { + return (int) map.entrySet().stream() + .filter(entry -> entry.getValue() + timeToLive > currentTime).count(); + } +} + +/** + * Your AuthenticationManager object will be instantiated and called as such: + * AuthenticationManager obj = new AuthenticationManager(timeToLive); + * obj.generate(tokenId,currentTime); + * obj.renew(tokenId,currentTime); + * int param_3 = obj.countUnexpiredTokens(currentTime); + */ diff --git a/Medium/Design Browser History.java b/Medium/Design Browser History.java index fb5db3bb..63799e9d 100644 --- a/Medium/Design Browser History.java +++ b/Medium/Design Browser History.java @@ -1,41 +1,32 @@ class BrowserHistory { - - Node root; - public BrowserHistory(String homepage) { - root = new Node(homepage); - } + + private final Stack history; + private final Stack future; - public void visit(String url) { - Node node = new Node(url); - root.next = null; - root.next = node; - node.prev = root; - root = root.next; - } - - public String back(int steps) { - while (steps-- > 0 && root.prev != null) { - root = root.prev; + public BrowserHistory(String homepage) { + this.history = new Stack<>(); + this.future = new Stack<>(); + this.history.push(homepage); } - return root.val; - } - - public String forward(int steps) { - while (steps-- > 0 && root.next != null) { - root = root.next; + + public void visit(String url) { + future.removeAllElements(); + history.push(url); + } + + public String back(int steps) { + while (steps-- > 0 && history.size() > 1) { + future.push(history.pop()); + } + return history.peek(); + } + + public String forward(int steps) { + while (steps-- > 0 && !future.isEmpty()) { + history.push(future.pop()); + } + return history.peek(); } - return root.val; - } -} - -class Node { - String val; - Node next; - Node prev; - - public Node(String val) { - this.val = val; - } } /** diff --git a/Medium/Design Circular Deque.java b/Medium/Design Circular Deque.java index 38b8650c..66667ed5 100644 --- a/Medium/Design Circular Deque.java +++ b/Medium/Design Circular Deque.java @@ -1,106 +1,90 @@ class MyCircularDeque { - DequeNode head; - DequeNode tail; - int k; - int currCapacity; - /** Initialize your data structure here. Set the size of the deque to be k. */ - public MyCircularDeque(int k) { - currCapacity = 0; - this.k = k; - head = new DequeNode(-1); - tail = new DequeNode(-1); - head.front = tail; - tail.back = head; - } + private final Node head; + private final Node tail; + private final int capacity; + private int size; - /** Adds an item at the front of Deque. Return true if the operation is successful. */ - public boolean insertFront(int value) { - if (isFull()) { - return false; + public MyCircularDeque(int k) { + head = new Node(-1); + tail = new Node(-1); + head.next = tail; + tail.prev = head; + capacity = k; + size = 0; } - DequeNode node = new DequeNode(value); - node.front = head.front; - head.front.back = node; - node.back = head; - head.front = node; - currCapacity++; - return true; - } - /** Adds an item at the rear of Deque. Return true if the operation is successful. */ - public boolean insertLast(int value) { - if (isFull()) { - return false; + public boolean insertFront(int value) { + if (size == capacity) { + return false; + } + Node node = new Node(value); + node.next = head.next; + node.prev = head; + head.next.prev = node; + head.next = node; + size++; + return true; } - DequeNode node = new DequeNode(value); - node.front = tail; - node.back = tail.back; - tail.back.front = node; - tail.back = node; - currCapacity++; - return true; - } - /** Deletes an item from the front of Deque. Return true if the operation is successful. */ - public boolean deleteFront() { - if (isEmpty()) { - return false; + public boolean insertLast(int value) { + if (size == capacity) { + return false; + } + Node node = new Node(value); + node.prev = tail.prev; + node.next = tail; + tail.prev.next = node; + tail.prev = node; + size++; + return true; } - DequeNode next = head.front.front; - head.front = next; - next.back = head; - currCapacity--; - return true; - } - /** Deletes an item from the rear of Deque. Return true if the operation is successful. */ - public boolean deleteLast() { - if (isEmpty()) { - return false; + public boolean deleteFront() { + if (size == 0) { + return false; + } + head.next.next.prev = head; + head.next = head.next.next; + size--; + return true; } - DequeNode prev = tail.back.back; - tail.back = prev; - prev.front = tail; - currCapacity--; - return true; - } - /** Get the front item from the deque. */ - public int getFront() { - if (isEmpty()) { - return -1; + public boolean deleteLast() { + if (size == 0) { + return false; + } + tail.prev.prev.next = tail; + tail.prev = tail.prev.prev; + size--; + return true; } - return head.front.val; - } - /** Get the last item from the deque. */ - public int getRear() { - if (isEmpty()) { - return -1; + public int getFront() { + return head.next.value; } - return tail.back.val; - } - /** Checks whether the circular deque is empty or not. */ - public boolean isEmpty() { - return currCapacity == 0; - } + public int getRear() { + return tail.prev.value; + } - /** Checks whether the circular deque is full or not. */ - public boolean isFull() { - return currCapacity == k; - } -} + public boolean isEmpty() { + return size == 0; + } -class DequeNode { - int val; - DequeNode front; - DequeNode back; - - public DequeNode(int val) { - this.val = val; - } + public boolean isFull() { + return size == capacity; + } + + static class Node { + int value; + Node next; + Node prev; + + Node(int value) { + this.value = value; + } + } } /** diff --git a/Medium/Design Circular Queue.java b/Medium/Design Circular Queue.java index ee595135..d5f90b31 100644 --- a/Medium/Design Circular Queue.java +++ b/Medium/Design Circular Queue.java @@ -1,60 +1,52 @@ class MyCircularQueue { + + private Integer[] queue; + private int valueCursor; + private int emptyCursor; - /** Initialize your data structure here. Set the size of the queue to be k. */ - int[] queue; - int start; - int end; - int k; public MyCircularQueue(int k) { - this.k = k; - queue = new int[k]; - start = 0; - end = 0; - Arrays.fill(queue, -1); + this.queue = new Integer[k]; + this.valueCursor = 0; + this.emptyCursor = 0; } - /** Insert an element into the circular queue. Return true if the operation is successful. */ public boolean enQueue(int value) { - if (end == start && queue[end] != -1) { + if (queue[emptyCursor] != null) { return false; } - queue[end++] = value; - if (end == k) { - end = 0; + queue[emptyCursor++] = value; + if (emptyCursor == queue.length) { + emptyCursor = 0; } return true; } - /** Delete an element from the circular queue. Return true if the operation is successful. */ public boolean deQueue() { - if (queue[start] == -1) { + if (queue[valueCursor] == null) { return false; } - queue[start++] = -1; - if (start == k) { - start = 0; + queue[valueCursor++] = null; + if (valueCursor == queue.length) { + valueCursor = 0; } return true; } - /** Get the front item from the queue. */ public int Front() { - return queue[start]; + return queue[valueCursor] == null ? -1 : queue[valueCursor]; } - /** Get the last item from the queue. */ public int Rear() { - return end == 0 ? queue[k - 1] : queue[end - 1]; + int idx = emptyCursor == 0 ? queue.length - 1 : emptyCursor - 1; + return queue[idx] == null ? -1 : queue[idx]; } - /** Checks whether the circular queue is empty or not. */ public boolean isEmpty() { - return start == end && queue[end] == -1; + return queue[valueCursor] == null; } - /** Checks whether the circular queue is full or not. */ public boolean isFull() { - return start == end && queue[end] != -1; + return queue[emptyCursor] != null; } } diff --git a/Medium/Design File System.java b/Medium/Design File System.java index 91a8dccb..aef4ab97 100644 --- a/Medium/Design File System.java +++ b/Medium/Design File System.java @@ -1,57 +1,51 @@ class FileSystem { - FileNode root; + + private FileNode root; + public FileSystem() { - root = new FileNode("-"); + this.root = new FileNode(); } public boolean createPath(String path, int value) { - FileNode curr = root; - String[] directories = path.split("/"); - for (int i = 0; i < directories.length; i++) { - if (directories[i].equals("")) { - continue; + String[] split = path.split("/"); + FileNode node = root; + for (int i = 1; i < split.length - 1; i++) { + if (!node.children.containsKey(split[i])) { + return false; } - if (!curr.children.containsKey(directories[i])) { - if (i != directories.length - 1) { - return false; - } - curr.children.put(directories[i], new FileNode(directories[i])); - } - curr = curr.children.get(directories[i]); + node = node.children.get(split[i]); } - if (curr.val != -1) { + if (node.children.containsKey(split[split.length - 1])) { return false; } - curr.val = value; + node.children.put(split[split.length - 1], new FileNode(value)); return true; } public int get(String path) { - FileNode curr = root; - String[] directories = path.split("/"); - for (int i = 0; i < directories.length; i++) { - if (directories[i].equals("")) { - continue; - } - if (!curr.children.containsKey(directories[i])) { + String[] split = path.split("/"); + FileNode node = root; + for (int i = 1; i < split.length; i++) { + if (!node.children.containsKey(split[i])) { return -1; } - curr = curr.children.get(directories[i]); + node = node.children.get(split[i]); } - return curr.val; + return node.value == null ? -1 : node.value; } -} + private static class FileNode { + private final Map children; + private Integer value; + + public FileNode() { + this.children = new HashMap<>(); + } -class FileNode { - String fileName; - int val; - Map children; - - public FileNode(String fileName) { - this.fileName = fileName; - val = -1; - children = new HashMap<>(); + public FileNode(Integer value) { + this.children = new HashMap<>(); + this.value = value; + } } } diff --git a/Medium/Design Front Middle Back Queue.java b/Medium/Design Front Middle Back Queue.java new file mode 100644 index 00000000..cee37d34 --- /dev/null +++ b/Medium/Design Front Middle Back Queue.java @@ -0,0 +1,64 @@ +class FrontMiddleBackQueue { + + Deque frontQueue; + Deque backQueue; + + public FrontMiddleBackQueue() { + frontQueue = new ArrayDeque<>(); + backQueue = new ArrayDeque<>(); + } + + public void pushFront(int val) { + frontQueue.addFirst(val); + } + + public void pushMiddle(int val) { + while (frontQueue.size() + 1 < backQueue.size()) { + frontQueue.addLast(backQueue.removeFirst()); + } + while (frontQueue.size() > backQueue.size()) { + backQueue.addFirst(frontQueue.removeLast()); + } + frontQueue.addLast(val); + } + + public void pushBack(int val) { + backQueue.addLast(val); + } + + public int popFront() { + return frontQueue.isEmpty() + ? (backQueue.isEmpty() ? -1 : backQueue.removeFirst()) + : frontQueue.removeFirst(); + } + + public int popMiddle() { + if (frontQueue.isEmpty() && backQueue.isEmpty()) { + return -1; + } + while (frontQueue.size() < backQueue.size()) { + frontQueue.addLast(backQueue.removeFirst()); + } + while (frontQueue.size() > backQueue.size() + 1) { + backQueue.addFirst(frontQueue.removeLast()); + } + return !frontQueue.isEmpty() ? frontQueue.removeLast() : backQueue.removeFirst(); + } + + public int popBack() { + return backQueue.isEmpty() + ? (frontQueue.isEmpty() ? -1 : frontQueue.removeLast()) + : backQueue.removeLast(); + } +} + +/** + * Your FrontMiddleBackQueue object will be instantiated and called as such: + * FrontMiddleBackQueue obj = new FrontMiddleBackQueue(); + * obj.pushFront(val); + * obj.pushMiddle(val); + * obj.pushBack(val); + * int param_4 = obj.popFront(); + * int param_5 = obj.popMiddle(); + * int param_6 = obj.popBack(); + */ diff --git a/Medium/Design Hit Counter.java b/Medium/Design Hit Counter.java index 374d33c3..c241a419 100644 --- a/Medium/Design Hit Counter.java +++ b/Medium/Design Hit Counter.java @@ -1,37 +1,28 @@ class HitCounter { + + private Deque record; + private int count; + + public HitCounter() { + this.record = new LinkedList<>(); + this.count = 0; + } - /** Initialize your data structure here. */ - int[] times; - int[] hits; - public HitCounter() { - times = new int[300]; - hits = new int[300]; + public void hit(int timestamp) { + if (!record.isEmpty() && record.getLast()[0] == timestamp) { + record.getLast()[1]++; + } else { + record.add(new int[]{timestamp, 1}); } - - /** Record a hit. - @param timestamp - The current timestamp (in seconds granularity). */ - public void hit(int timestamp) { - int idx = timestamp % 300; - if (times[idx] != timestamp) { - times[idx] = timestamp; - hits[idx] = 1; - } - else { - hits[idx]++; - } - } - - /** Return the number of hits in the past 5 minutes. - @param timestamp - The current timestamp (in seconds granularity). */ - public int getHits(int timestamp) { - int totalCount = 0; - for (int i = 0; i < 300; i++) { - if (timestamp - times[i] < 300) { - totalCount += hits[i]; - } - } - return totalCount; + this.count++; + } + + public int getHits(int timestamp) { + while (!record.isEmpty() && timestamp - record.getFirst()[0] >= 300) { + this.count -= record.removeFirst()[1]; } + return this.count; + } } /** diff --git a/Medium/Design SQL.java b/Medium/Design SQL.java new file mode 100644 index 00000000..644009b1 --- /dev/null +++ b/Medium/Design SQL.java @@ -0,0 +1,47 @@ +class SQL { + + private final Map>> database; + private final Map tableIdMap; + + public SQL(List tableNames, List columns) { + this.database = new HashMap<>(); + this.tableIdMap = new HashMap<>(); + for (String name : tableNames) { + database.put(name, new HashMap<>()); + tableIdMap.put(name, 1); + } + } + + public void insertRow(String tableName, List row) { + // Select the table + Map> table = this.database.get(tableName); + // Insert row in the table + table.put(tableIdMap.get(tableName), row); + // Increment rowId for the table + tableIdMap.put(tableName, tableIdMap.get(tableName) + 1); + } + + public void deleteRow(String tableName, int rowId) { + // Select the table + Map> table = this.database.get(tableName); + // Delete the row against the rowId + table.remove(rowId); + } + + public String selectCell(String tableName, int rowId, int columnId) { + // Select the table + Map> table = this.database.get(tableName); + // Select row + List row = table.get(rowId); + // Select column + return row.get(columnId - 1); + } +} + +/** + * Your SQL object will be instantiated and called as such: + * SQL obj = new SQL(names, columns); + * obj.insertRow(name,row); + * obj.deleteRow(name,rowId); + * String param_3 = obj.selectCell(name,rowId,columnId); + */ diff --git a/Medium/Design Snake Game.java b/Medium/Design Snake Game.java new file mode 100644 index 00000000..dd645d15 --- /dev/null +++ b/Medium/Design Snake Game.java @@ -0,0 +1,78 @@ +class SnakeGame { + + private final Deque snake; + private final Queue foodQueue; + private final Set snakeBody; + private final int width; + private final int height; + private int score; + + public SnakeGame(int width, int height, int[][] food) { + this.snake = new ArrayDeque<>(); + this.snake.addFirst(new int[]{0, 0}); + this.foodQueue = new LinkedList<>(); + this.foodQueue.addAll(Arrays.asList(food)); + this.snakeBody = new HashSet<>(); + this.snakeBody.add(0 + "|" + 0); + this.width = width; + this.height = height; + this.score = 0; + } + + public int move(String direction) { + int[] nextMove = getNextMove(direction); + if (!isMoveWithInBound(nextMove)) { + return -1; + } + moveSnake(nextMove); + if (isBitingItself(nextMove)) { + return -1; + } + this.snakeBody.add(nextMove[0] + "|" + nextMove[1]); + return score; + } + + private int[] getNextMove(String direction) { + int[] nextMove = Arrays.copyOf(this.snake.peekFirst(), 2); + switch (direction) { + case "L" -> nextMove[1]--; + case "R" -> nextMove[1]++; + case "U" -> nextMove[0]--; + case "D" -> nextMove[0]++; + default -> {} + } + return nextMove; + } + + private boolean isMoveWithInBound(int[] move) { + int x = move[0]; + int y = move[1]; + return x >= 0 && y >= 0 && x < this.height && y < this.width; + } + + private void moveSnake(int[] move) { + this.snake.addFirst(move); + if (snakeEatsFood(move)) { + this.foodQueue.remove(); + this.score++; + } else { + int[] tail = this.snake.removeLast(); + this.snakeBody.remove(tail[0] + "|" + tail[1]); + } + } + + private boolean snakeEatsFood(int[] move) { + return !this.foodQueue.isEmpty() && move[0] == this.foodQueue.peek()[0] && move[1] == this.foodQueue.peek()[1]; + } + + private boolean isBitingItself(int[] move) { + String key = move[0] + "|" + move[1]; + return this.snakeBody.contains(key); + } +} + +/** + * Your SnakeGame object will be instantiated and called as such: + * SnakeGame obj = new SnakeGame(width, height, food); + * int param_1 = obj.move(direction); + */ diff --git a/Medium/Design Spreadsheet.java b/Medium/Design Spreadsheet.java new file mode 100644 index 00000000..e41fc142 --- /dev/null +++ b/Medium/Design Spreadsheet.java @@ -0,0 +1,47 @@ +class Spreadsheet { + + private final Map> sheet; + + public Spreadsheet(int rows) { + sheet = new HashMap<>(); + for (char c = 'A'; c <= 'Z'; c++) { + sheet.put(c, new HashMap<>()); + } + } + + public void setCell(String cell, int value) { + char column = cell.charAt(0); + int rowNumber = Integer.parseInt(cell.substring(1)); + Map row = sheet.get(column); + row.put(rowNumber, value); + } + + public void resetCell(String cell) { + setCell(cell, 0); + } + + public int getValue(String formula) { + String[] split = formula.split("\\+"); + String cellOne = split[0].substring(1); + String cellTwo = split[1]; + return getCellValue(cellOne) + getCellValue(cellTwo); + } + + private int getCellValue(String cell) { + if (!Character.isLetter(cell.charAt(0))) { + return Integer.parseInt(cell); + } + char column = cell.charAt(0); + int rowNumber = Integer.parseInt(cell.substring(1)); + Map row = sheet.get(column); + return row.getOrDefault(rowNumber, 0); + } +} + +/** + * Your Spreadsheet object will be instantiated and called as such: + * Spreadsheet obj = new Spreadsheet(rows); + * obj.setCell(cell,value); + * obj.resetCell(cell); + * int param_3 = obj.getValue(formula); + */ diff --git a/Medium/Design Tic-Tac-Toe.java b/Medium/Design Tic-Tac-Toe.java index 35c3bd4b..50b57aea 100644 --- a/Medium/Design Tic-Tac-Toe.java +++ b/Medium/Design Tic-Tac-Toe.java @@ -1,66 +1,50 @@ class TicTacToe { - /** Initialize your data structure here. */ - int[][] board; - Map> rowMap; - Map> colMap; - Map leftDiagonalMap; - Map rightDiagonalMap; - int n; + private int n; + private Map> rowMapping; + private Map> colMapping; + private Map> diagonalMapping; + + private final int LEFT_DIAGONAL = 1; + private final int RIGHT_DIAGONAL = -1; + public TicTacToe(int n) { - board = new int[n][n]; - rowMap = new HashMap<>(); - colMap = new HashMap<>(); - leftDiagonalMap = new HashMap<>(); - rightDiagonalMap = new HashMap<>(); this.n = n; + this.rowMapping = new HashMap<>(); + this.colMapping = new HashMap<>(); + this.diagonalMapping = new HashMap<>(); + this.diagonalMapping.put(LEFT_DIAGONAL, new HashMap<>()); + this.diagonalMapping.put(RIGHT_DIAGONAL, new HashMap<>()); } - /** Player {player} makes a move at ({row}, {col}). - @param row The row of the board. - @param col The column of the board. - @param player The player, can be either 1 or 2. - @return The current winning condition, can be either: - 0: No one wins. - 1: Player 1 wins. - 2: Player 2 wins. */ public int move(int row, int col, int player) { - if (!rowMap.containsKey(row)) { - Map map = new HashMap<>(); - rowMap.put(row, map); - } - rowMap.get(row).put(player, rowMap.get(row).getOrDefault(player, 0) + 1); - if (ifWinner(rowMap.get(row), player)) { - return player; - } - if (!colMap.containsKey(col)) { - Map map = new HashMap<>(); - colMap.put(col, map); - } - colMap.get(col).put(player, colMap.get(col).getOrDefault(player, 0) + 1); - if (ifWinner(colMap.get(col), player)) { - return player; - } - if (row == col) { - leftDiagonalMap.put(player, leftDiagonalMap.getOrDefault(player, 0) + 1); - } - if (ifWinner(leftDiagonalMap, player)) { - return player; - } - if (row + col == n - 1) { - rightDiagonalMap.put(player, rightDiagonalMap.getOrDefault(player, 0) + 1); - } - if (ifWinner(rightDiagonalMap, player)) { + recordMove(row, col, player); + if (isWinnerFound(row, col, player)) { return player; } return 0; } - private boolean ifWinner(Map map, int player) { - if (map.size() > 1) { - return false; + private void recordMove(int row, int col, int player) { + this.rowMapping.computeIfAbsent(row, k -> new HashMap<>()); + this.colMapping.computeIfAbsent(col, k -> new HashMap<>()); + this.rowMapping.get(row).put(player, this.rowMapping.get(row).getOrDefault(player, 0) + 1); + this.colMapping.get(col).put(player, this.colMapping.get(col).getOrDefault(player, 0) + 1); + if (row == col) { + this.diagonalMapping.get(LEFT_DIAGONAL) + .put(player, this.diagonalMapping.get(LEFT_DIAGONAL).getOrDefault(player, 0) + 1); + } + if (row + col + 1 == this.n) { + this.diagonalMapping.get(RIGHT_DIAGONAL) + .put(player, this.diagonalMapping.get(RIGHT_DIAGONAL).getOrDefault(player, 0) + 1); } - return map.values().stream().reduce(0, Integer::sum) == n; + } + + private boolean isWinnerFound(int row, int col, int player) { + return this.rowMapping.get(row).get(player) == this.n || + this.colMapping.get(col).get(player) == this.n || + this.diagonalMapping.get(LEFT_DIAGONAL).getOrDefault(player, 0) == this.n || + this.diagonalMapping.get(RIGHT_DIAGONAL).getOrDefault(player, 0) == this.n; } } diff --git a/Medium/Design Twitter.java b/Medium/Design Twitter.java index 65b71c71..8009a1d6 100644 --- a/Medium/Design Twitter.java +++ b/Medium/Design Twitter.java @@ -1,160 +1,72 @@ -class Twitter { - - /** Initialize your data structure here. */ - Map userMap; - Map> followingMap; - Map> followerMap; - int tweetTimeStamp; - - public Twitter() { - followingMap = new HashMap<>(); - userMap = new HashMap<>(); - followerMap = new HashMap<>(); - tweetTimeStamp = 0; - } - - /** Compose a new tweet. */ - public void postTweet(int userId, int tweetId) { - Tweet tweet = new Tweet(tweetId, userId, tweetTimeStamp); - tweetTimeStamp++; - - createUserIfAbsent(userId); - - userMap.get(userId).topTweets.add(tweet); - List followers = followerMap.getOrDefault(userMap.get(userId), new ArrayList<>()); - for (User follower : followers) { - follower.topTweets.add(tweet); - } - } - - /** Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent. */ - public List getNewsFeed(int userId) { - if (!userMap.containsKey(userId)) { - return new ArrayList<>(); - } - - List topTweetIds = new ArrayList<>(); - Set tweetIdSet = new HashSet<>(); - List topTweets = new ArrayList<>(); - - PriorityQueue pq = userMap.get(userId).topTweets; - int count = 10; - - while (count > 0 && !pq.isEmpty()) { - Tweet tweet = pq.poll(); - topTweets.add(tweet); - - List usersFollowing = followingMap.get(userMap.get(userId)); - - if ((userMap.containsKey(tweet.userId) && usersFollowing.contains(userMap.get(tweet.userId))) || - tweet.userId == userId) { - if (!tweetIdSet.contains(tweet.tweetId)) { - topTweetIds.add(tweet.tweetId); - tweetIdSet.add(tweet.tweetId); - count--; - } - } - } - - pq.addAll(topTweets); - - return topTweetIds; - } - - /** Follower follows a followee. If the operation is invalid, it should be a no-op. */ - public void follow(int followerId, int followeeId) { - if (followeeId == followerId) { - return; - } +import java.util.Map.Entry; - createUserIfAbsent(followeeId); - createUserIfAbsent(followerId); - if (!followingMap.get(userMap.get(followerId)).contains(userMap.get(followeeId))) { - followingMap.get(userMap.get(followerId)).add(userMap.get(followeeId)); - userMap.get(followerId).topTweets.addAll(userMap.get(followeeId).topTweets); - } - - if (!followerMap.getOrDefault(userMap.get(followeeId), new ArrayList<>()).contains(userMap.get(followerId))) { - followerMap.get(userMap.get(followeeId)).add(userMap.get(followerId)); - } +class Twitter { - } + private final Map> userFollowing; + private final Map userToTweet; + private int timestamp; - private void createUserIfAbsent(int id) { - if (!userMap.containsKey(id)) { - User newUser = new User(id); - userMap.put(id, newUser); - List followers = new ArrayList<>(); - List following = new ArrayList<>(); + public Twitter() { + this.userFollowing = new HashMap<>(); + this.timestamp = 0; + this.userToTweet = new HashMap<>(); + } - followingMap.put(newUser, following); - followerMap.put(newUser, followers); - } + public void postTweet(int userId, int tweetId) { + TweetNode tweetNode = new TweetNode(tweetId, this.timestamp++); + if (this.userToTweet.containsKey(userId)) { + tweetNode.next = this.userToTweet.get(userId); } - - /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ - public void unfollow(int followerId, int followeeId) { - if (!userMap.containsKey(followeeId)) { - return; - } - - if (!userMap.containsKey(followerId)) { - return; - } - - if (followingMap.get(userMap.get(followerId)).contains(userMap.get(followeeId))) { - followingMap.get(userMap.get(followerId)).remove(userMap.get(followeeId)); - } + this.userToTweet.put(userId, tweetNode); + } + + public List getNewsFeed(int userId) { + PriorityQueue priorityQueue = + new PriorityQueue<>((o1, o2) -> o2.timestamp - o1.timestamp); + priorityQueue.addAll( + this.userToTweet.entrySet().stream() + .filter( + entry -> + entry.getKey() == userId + || this.userFollowing + .getOrDefault(userId, new HashSet<>()) + .contains(entry.getKey())) + .map(Entry::getValue) + .collect(Collectors.toList())); + List result = new ArrayList<>(); + while (!priorityQueue.isEmpty() && result.size() < 10) { + TweetNode removed = priorityQueue.remove(); + result.add(removed.tweetId); + if (removed.next != null) { + priorityQueue.add(removed.next); + } } -} - -class User { - public int id; - public List followers; - PriorityQueue topTweets; + return result; + } - public User(int id) { - this.id = id; - this.followers = new ArrayList<>(); - this.topTweets = new PriorityQueue<>(new Comparator() { - @Override - public int compare(Tweet o1, Tweet o2) { - return o2.timestamp - o1.timestamp; - } - }); - } + public void follow(int followerId, int followeeId) { + this.userFollowing.computeIfAbsent(followerId, k -> new HashSet<>()).add(followeeId); + } - @Override - public String toString() { - return "User{" + - "id=" + id + - '}'; + public void unfollow(int followerId, int followeeId) { + if (this.userFollowing.getOrDefault(followerId, new HashSet<>()).contains(followeeId)) { + this.userFollowing.get(followerId).remove(followeeId); } -} + } -class Tweet { - public int tweetId; - public int userId; - public int timestamp; + private static class TweetNode { + int tweetId; + int timestamp; + TweetNode next; - public Tweet(int tweetId, int userId, int timestamp) { - this.tweetId = tweetId; - this.userId = userId; - this.timestamp = timestamp; - } - - @Override - public String toString() { - return "Tweet{" + - "tweetId=" + tweetId + - ", userId=" + userId + - '}'; + public TweetNode(int tweetId, int timestamp) { + this.tweetId = tweetId; + this.timestamp = timestamp; } + } } - - /** * Your Twitter object will be instantiated and called as such: * Twitter obj = new Twitter(); diff --git a/Medium/Design Underground System.java b/Medium/Design Underground System.java index 730aaa49..6297656a 100644 --- a/Medium/Design Underground System.java +++ b/Medium/Design Underground System.java @@ -1,30 +1,37 @@ class UndergroundSystem { - Map checkInMap; - Map timeMap; - Map countMap; - public UndergroundSystem() { - checkInMap = new HashMap<>(); - timeMap = new HashMap<>(); - countMap = new HashMap<>(); - } + + private final Map customerToCheckInMapping; + private final Map startEndStationTotalTimeMapping; + private final Map startEndStationCountMapping; - public void checkIn(int id, String stationName, int t) { - checkInMap.put(id, stationName + "," + t); - } - - public void checkOut(int id, String stationName, int t) { - String val = checkInMap.get(id); - String prevStationName = val.split(",")[0]; - int prevTime = Integer.parseInt(val.split(",")[1]); - String key = prevStationName + "|" + stationName; - timeMap.put(key, timeMap.getOrDefault(key, 0) + t - prevTime); - countMap.put(key, countMap.getOrDefault(key, 0) + 1); - } - - public double getAverageTime(String startStation, String endStation) { - String key = startStation + "|" + endStation; - return ((double) timeMap.get(key)) / countMap.get(key); - } + public UndergroundSystem() { + this.customerToCheckInMapping = new HashMap<>(); + this.startEndStationTotalTimeMapping = new HashMap<>(); + this.startEndStationCountMapping = new HashMap<>(); + } + + public void checkIn(int id, String stationName, int t) { + StationTimePair pair = new StationTimePair(stationName, t); + customerToCheckInMapping.put(id, pair); + } + + public void checkOut(int id, String stationName, int t) { + StationTimePair pair = customerToCheckInMapping.get(id); + String key = pair.station() + "|" + stationName; + int totalTime = t - pair.time(); + startEndStationTotalTimeMapping.put(key, startEndStationTotalTimeMapping.getOrDefault(key, 0) + totalTime); + startEndStationCountMapping.put(key, startEndStationCountMapping.getOrDefault(key, 0) + 1); + } + + public double getAverageTime(String startStation, String endStation) { + String key = startStation + "|" + endStation; + if (!startEndStationTotalTimeMapping.containsKey(key)) { + return 0.0; + } + return ((double) startEndStationTotalTimeMapping.get(key)) / startEndStationCountMapping.get(key); + } + + static record StationTimePair(String station, int time) {} } /** diff --git a/Medium/Design a File Sharing System.java b/Medium/Design a File Sharing System.java index 2f6c3de7..b5bba82b 100644 --- a/Medium/Design a File Sharing System.java +++ b/Medium/Design a File Sharing System.java @@ -1,57 +1,50 @@ class FileSharing { - Map> chunkToUserMap; - Map> userToChunkMap; - int id; - PriorityQueue availableIds; - public FileSharing(int m) { - id = 1; - chunkToUserMap = new HashMap<>(); - userToChunkMap = new HashMap<>(); - for (int i = 1; i <= m; i++) { - chunkToUserMap.put(i, new HashSet<>()); - } - availableIds = new PriorityQueue<>(); - } - public int join(List ownedChunks) { - int userId = getUserId(); - userToChunkMap.put(userId, new HashSet<>(ownedChunks)); - for (Integer chunk : ownedChunks) { - chunkToUserMap.get(chunk).add(userId); - } - return userId; - } - - private int getUserId() { - if (availableIds.isEmpty()) { - return id++; + private final PriorityQueue userIdsInSystem; + private final Map> chunkToUserIdMapping; + private final Map> userIdToChunkMapping; + + public FileSharing(int m) { + this.userIdsInSystem = new PriorityQueue<>(); + this.userIdsInSystem.add(1); + this.chunkToUserIdMapping = new HashMap<>(); + for (int i = 1; i <= m; i++) { + chunkToUserIdMapping.put(i, new HashSet<>()); + } + this.userIdToChunkMapping = new HashMap<>(); } - return availableIds.poll(); - } - public void leave(int userID) { - Set chunksOwned = userToChunkMap.get(userID); - userToChunkMap.remove(userID); - for (Integer chunk : chunksOwned) { - chunkToUserMap.get(chunk).remove(userID); + public int join(List ownedChunks) { + int currUserId = this.userIdsInSystem.poll(); + if (this.userIdsInSystem.isEmpty()) { + this.userIdsInSystem.add(currUserId + 1); + } + this.userIdToChunkMapping.computeIfAbsent(currUserId, k -> new HashSet<>()); + for (Integer chunk : ownedChunks) { + this.chunkToUserIdMapping.get(chunk).add(currUserId); + this.userIdToChunkMapping.get(currUserId).add(chunk); + } + return currUserId; } - availableIds.add(userID); - } - public List request(int userID, int chunkID) { - Set usersOwningChunk = chunkToUserMap.get(chunkID); - Iterator iterator = usersOwningChunk.iterator(); - List users = new ArrayList<>(); - while (iterator.hasNext()) { - users.add(iterator.next()); + public void leave(int userID) { + this.userIdsInSystem.add(userID); + Set chunksOwned = this.userIdToChunkMapping.get(userID); + this.userIdToChunkMapping.remove(userID); + for (Integer chunk : chunksOwned) { + this.chunkToUserIdMapping.get(chunk).remove(userID); + } } - if (!usersOwningChunk.contains(userID) && usersOwningChunk.size() > 0) { - userToChunkMap.get(userID).add(chunkID); - chunkToUserMap.get(chunkID).add(userID); + + public List request(int userID, int chunkID) { + if (this.chunkToUserIdMapping.get(chunkID).isEmpty()) { + return new ArrayList<>(); + } + List usersOwningChunk = this.chunkToUserIdMapping.get(chunkID).stream().sorted().toList(); + this.userIdToChunkMapping.get(userID).add(chunkID); + this.chunkToUserIdMapping.get(chunkID).add(userID); + return usersOwningChunk; } - Collections.sort(users); - return users; - } } /** diff --git a/Medium/Design a Food Rating System.java b/Medium/Design a Food Rating System.java new file mode 100644 index 00000000..71c55477 --- /dev/null +++ b/Medium/Design a Food Rating System.java @@ -0,0 +1,53 @@ +class FoodRatings { + + private final Map foodToRating; + + private final Map foodToCuisine; + + private final Map> cuisineToFood; + + public FoodRatings(String[] foods, String[] cuisines, int[] ratings) { + this.foodToRating = new HashMap<>(); + this.foodToCuisine = new HashMap<>(); + this.cuisineToFood = new HashMap<>(); + for (int i = 0; i < foods.length; i++) { + String food = foods[i]; + String cuisine = cuisines[i]; + int rating = ratings[i]; + foodToRating.put(food, rating); + foodToCuisine.put(food, cuisine); + cuisineToFood.computeIfAbsent(cuisine, k -> new PriorityQueue<>()).add(new Food(food, rating)); + } + } + + public void changeRating(String food, int newRating) { + this.foodToRating.put(food, newRating); + String cuisine = foodToCuisine.get(food); + cuisineToFood.get(cuisine).add(new Food(food, newRating)); + } + + public String highestRated(String cuisine) { + Food highestRatedFood = cuisineToFood.get(cuisine).peek(); + while (foodToRating.get(highestRatedFood.name) != highestRatedFood.rating) { + cuisineToFood.get(cuisine).poll(); + highestRatedFood = cuisineToFood.get(cuisine).peek(); + } + return highestRatedFood.name; + } + + private record Food(String name, int rating) implements Comparable { + @Override + public int compareTo(Food o) { + int c = o.rating - rating; + return c == 0 ? name.compareTo(o.name) : c; + } + } +} + + +/** + * Your FoodRatings object will be instantiated and called as such: + * FoodRatings obj = new FoodRatings(foods, cuisines, ratings); + * obj.changeRating(food,newRating); + * String param_2 = obj.highestRated(cuisine); + */ diff --git a/Medium/Design a Number Container System.java b/Medium/Design a Number Container System.java new file mode 100644 index 00000000..26a3e843 --- /dev/null +++ b/Medium/Design a Number Container System.java @@ -0,0 +1,34 @@ +class NumberContainers { + + private final Map> numberToIndex; + private final Map indexToNumber; + + public NumberContainers() { + this.numberToIndex = new HashMap<>(); + this.indexToNumber = new HashMap<>(); + } + + public void change(int index, int number) { + if (indexToNumber.containsKey(index)) { + int prevNumber = indexToNumber.get(index); + numberToIndex.get(prevNumber).remove(index); + } + indexToNumber.put(index, number); + numberToIndex.computeIfAbsent(number, k -> new TreeSet<>()).add(index); + } + + public int find(int number) { + TreeSet indices = numberToIndex.getOrDefault(number, new TreeSet<>()); + if (indices.isEmpty()) { + return -1; + } + return indices.first(); + } +} + +/** + * Your NumberContainers object will be instantiated and called as such: + * NumberContainers obj = new NumberContainers(); + * obj.change(index,number); + * int param_2 = obj.find(number); + */ diff --git a/Medium/Design a Stack With Increment Operation.java b/Medium/Design a Stack With Increment Operation.java index 34f80a99..9e4ec3a3 100644 --- a/Medium/Design a Stack With Increment Operation.java +++ b/Medium/Design a Stack With Increment Operation.java @@ -1,38 +1,40 @@ class CustomStack { - Stack stack; - int maxSize; - int[] increment; - public CustomStack(int maxSize) { - this.maxSize = maxSize; - stack = new Stack<>(); - increment = new int[maxSize]; - } - public void push(int x) { - if (stack.size() < maxSize) { - stack.push(x); - } - } + private final int maxSize; + private final Stack stack; + private int[] increment; - public int pop() { - int idx = stack.size() - 1; - if (idx < 0) { - return -1; + public CustomStack(int maxSize) { + this.maxSize = maxSize; + this.stack = new Stack<>(); + this.increment = new int[maxSize]; } - if (idx > 0) { - increment[idx - 1] += increment[idx]; + + public void push(int x) { + if (stack.size() < maxSize) { + stack.push(x); + } } - int ans = stack.pop() + increment[idx]; - increment[idx] = 0; - return ans; - } - - public void increment(int k, int val) { - int idx = Math.min(k, stack.size()) - 1; - if (idx >= 0) { - increment[idx] += val; + + public int pop() { + int idx = stack.size() - 1; + if (idx < 0) { + return -1; + } + if (idx > 0) { + increment[idx - 1] += increment[idx]; + } + int result = stack.pop() + increment[idx]; + increment[idx] = 0; + return result; + } + + public void increment(int k, int val) { + int idx = Math.min(k, stack.size()) - 1; + if (idx >= 0) { + increment[idx] += val; + } } - } } /** diff --git a/Medium/Design an ATM Machine.java b/Medium/Design an ATM Machine.java new file mode 100644 index 00000000..b4888a7a --- /dev/null +++ b/Medium/Design an ATM Machine.java @@ -0,0 +1,43 @@ +class ATM { + + private long[] noteCount; + private int[] noteValue; + + public ATM() { + this.noteCount = new long[5]; + this.noteValue = new int[]{20, 50, 100, 200, 500}; + } + + public void deposit(int[] banknotesCount) { + for (int i = 0; i < banknotesCount.length; i++) { + this.noteCount[i] += banknotesCount[i]; + } + } + + public int[] withdraw(int amount) { + int[] resultNoteCount = new int[5]; + for (int i = this.noteValue.length - 1; i >= 0 && amount > 0; i--) { + if (amount >= this.noteValue[i]) { + long numOfNotes = Math.min(amount / this.noteValue[i], this.noteCount[i]); + amount -= this.noteValue[i] * numOfNotes; + resultNoteCount[i] = (int) numOfNotes; + } + } + if (amount > 0) { + return new int[]{-1}; + } + if (amount == 0) { + for (int i = 0; i < resultNoteCount.length; i++) { + this.noteCount[i] -= resultNoteCount[i]; + } + } + return resultNoteCount; + } +} + +/** + * Your ATM object will be instantiated and called as such: + * ATM obj = new ATM(); + * obj.deposit(banknotesCount); + * int[] param_2 = obj.withdraw(amount); + */ diff --git a/Medium/Design an Expression Tree With Evaluate Function.java b/Medium/Design an Expression Tree With Evaluate Function.java new file mode 100644 index 00000000..e01eb49f --- /dev/null +++ b/Medium/Design an Expression Tree With Evaluate Function.java @@ -0,0 +1,93 @@ +/** + * This is the interface for the expression tree Node. + * You should not remove it, and you can define some classes to implement it. + */ + +abstract class Node { + public abstract int evaluate(); + // define your fields here +}; + + +class NumericNode extends Node { + private int val; + + public NumericNode(int val) { + this.val = val; + } + + @Override + public int evaluate() { + return this.val; + } +} + + +class OperatorNode extends Node { + private char operator; + private Node left; + private Node right; + + public OperatorNode(char operator) { + this.operator = operator; + this.left = null; + this.right = null; + } + + @Override + public int evaluate() { + return switch(operator) { + case '+' -> left.evaluate() + right.evaluate(); + case '-' -> left.evaluate() - right.evaluate(); + case '*' -> left.evaluate() * right.evaluate(); + case '/' -> left.evaluate() / right.evaluate(); + default -> 0; + }; + } + + public void setRightNode(Node right) { + this.right = right; + } + + public void setLeftNode(Node left) { + this.left = left; + } +} + +/** + * This is the TreeBuilder class. + * You can treat it as the driver code that takes the postinfix input + * and returns the expression tree represnting it as a Node. + */ + +class TreeBuilder { + private static final Set OPERATORS = Set.of("+", "-", "/", "*"); + + Node buildTree(String[] postfix) { + int[] idx = {postfix.length - 1}; + return buildTree(postfix, idx); + } + + private Node buildTree(String[] postfix, int[] idx) { + if (idx[0] < 0) { + return null; + } + String val = postfix[idx[0]--]; + if (OPERATORS.contains(val)) { + OperatorNode node = new OperatorNode(val.charAt(0)); + node.setRightNode(buildTree(postfix, idx)); + node.setLeftNode(buildTree(postfix, idx)); + return node; + } + NumericNode node = new NumericNode(Integer.parseInt(val)); + return node; + } +}; + + +/** + * Your TreeBuilder object will be instantiated and called as such: + * TreeBuilder obj = new TreeBuilder(); + * Node expTree = obj.buildTree(postfix); + * int ans = expTree.evaluate(); + */ diff --git a/Medium/Determine if Two Strings Are Close.java b/Medium/Determine if Two Strings Are Close.java new file mode 100644 index 00000000..3a43fd6a --- /dev/null +++ b/Medium/Determine if Two Strings Are Close.java @@ -0,0 +1,30 @@ +class Solution { + public boolean closeStrings(String word1, String word2) { + if (word1.length() != word2.length()) { + return false; + } + int[] frequencyOne = getFrequencyArray(word1); + int[] frequencyTwo = getFrequencyArray(word2); + for (int i = 0; i < 26; i++) { + if (frequencyOne[i] == 0 && frequencyTwo[i] != 0) { + return false; + } + } + Arrays.sort(frequencyOne); + Arrays.sort(frequencyTwo); + for (int i = 0; i < 26; i++) { + if (frequencyOne[i] != frequencyTwo[i]) { + return false; + } + } + return true; + } + + private static int[] getFrequencyArray(String s) { + int[] frequency = new int[26]; + for (int i = 0; i < s.length(); i++) { + frequency[s.charAt(i) - 'a']++; + } + return frequency; + } +} diff --git a/Medium/Determine if a Cell Is Reachable at a Given Time.java b/Medium/Determine if a Cell Is Reachable at a Given Time.java new file mode 100644 index 00000000..37878fa8 --- /dev/null +++ b/Medium/Determine if a Cell Is Reachable at a Given Time.java @@ -0,0 +1,10 @@ +class Solution { + public boolean isReachableAtTime(int sx, int sy, int fx, int fy, int t) { + int xDiff = Math.abs(sx - fx); + int yDiff = Math.abs(sy - fy); + if (xDiff == 0 && yDiff == 0 && t == 1) { + return false; + } + return (Math.min(xDiff, yDiff) + Math.abs(xDiff - yDiff)) <= t; + } +} diff --git a/Medium/Determine the Minimum Sum of a k-avoiding Array.java b/Medium/Determine the Minimum Sum of a k-avoiding Array.java new file mode 100644 index 00000000..3eab331f --- /dev/null +++ b/Medium/Determine the Minimum Sum of a k-avoiding Array.java @@ -0,0 +1,18 @@ +class Solution { + public int minimumSum(int n, int k) { + Set set = new HashSet<>(); + set.add(1); + int sum = 1; + int next = 2; + while (n > 1) { + if (set.contains(k - next)) { + next++; + continue; + } + set.add(next); + sum += next++; + n--; + } + return sum; + } +} diff --git a/Medium/Detonate the Maximum Bombs.java b/Medium/Detonate the Maximum Bombs.java new file mode 100644 index 00000000..2dbecdc0 --- /dev/null +++ b/Medium/Detonate the Maximum Bombs.java @@ -0,0 +1,37 @@ +class Solution { + public int maximumDetonation(int[][] bombs) { + Map> graph = new HashMap<>(); + int n = bombs.length; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (i == j) { + continue; + } + int x1 = bombs[i][0]; + int y1 = bombs[i][1]; + int r = bombs[i][2]; + int x2 = bombs[j][0]; + int y2 = bombs[j][1]; + if ((long) r * r >= (long) (x1 - x2) * (x1 - x2) + (long) (y1 - y2) * (y1 - y2)) { + graph.computeIfAbsent(i, k -> new ArrayList<>()).add(j); + } + } + } + int result = 0; + for (int i = 0; i < n; i++) { + result = Math.max(result, dfs(i, new HashSet<>(), graph)); + } + return result; + } + + private int dfs(int curr, Set visited, Map> graph) { + visited.add(curr); + int count = 1; + for (Integer neighbor : graph.getOrDefault(curr, new ArrayList<>())) { + if (!visited.contains(neighbor)) { + count += dfs(neighbor, visited, graph); + } + } + return count; + } +} diff --git a/Medium/Diagonal Traverse II.java b/Medium/Diagonal Traverse II.java new file mode 100644 index 00000000..dabfc5ef --- /dev/null +++ b/Medium/Diagonal Traverse II.java @@ -0,0 +1,26 @@ +class Solution { + public int[] findDiagonalOrder(List> nums) { + Queue queue = new LinkedList<>(); + List result = new ArrayList<>(); + queue.add(new int[]{0, 0}); + while (!queue.isEmpty()) { + int[] removed = queue.remove(); + int x = removed[0]; + int y = removed[1]; + result.add(nums.get(x).get(y)); + // move down in column first + if (y == 0 && x + 1 < nums.size()) { + queue.add(new int[]{x + 1, y}); + } + // then pick the next element in row + if (y + 1 < nums.get(x).size()) { + queue.add(new int[]{x, y + 1}); + } + } + int[] ans = new int[result.size()]; + for (int i = 0; i < result.size(); i++) { + ans[i] = result.get(i); + } + return ans; + } +} diff --git a/Medium/Diagonal Traverse.java b/Medium/Diagonal Traverse.java index 0fc4371b..65c991a5 100644 --- a/Medium/Diagonal Traverse.java +++ b/Medium/Diagonal Traverse.java @@ -1,51 +1,33 @@ class Solution { - public int[] findDiagonalOrder(int[][] matrix) { - if (matrix.length == 0 || matrix[0].length == 0) { - return new int[]{}; + public int[] findDiagonalOrder(int[][] matrix) { + int dir = 0; + int x = 0; + int y = 0; + int numOfRows = matrix.length; + int numOfCols = matrix[0].length; + int[] ans = new int[numOfRows * numOfCols]; + for (int i = 0; i < numOfRows * numOfCols; i++) { + ans[i] = matrix[x][y]; + if ((x + y) % 2 == 0) { + if (y == numOfCols - 1) { + x++; + } else if (x == 0) { + y++; + } else { + x--; + y++; } - - int dir = 0; - int x = 0; - int y = 0; - int numOfRows = matrix.length; - int numOfCols = matrix[0].length; - int[] ans = new int[matrix.length * matrix[0].length]; - - for (int i = 0; i < numOfRows * numOfCols; i++) { - ans[i] = matrix[x][y]; - - if ((x + y) % 2 == 0) { - // If last column then go to next row - if (y == numOfCols - 1) { - x++; - } - // If first row but not last column then go to next column - else if (x == 0) { - y++; - } - // Go up - else { - x--; - y++; - } - } - else { - // If last row then go to next column - if (x == numOfRows - 1) { - y++; - } - // If first column but not last row then go to next row - else if (y == 0) { - x++; - } - // Go down - else { - x++; - y--; - } - } + } else { + if (x == numOfRows - 1) { + y++; + } else if (y == 0) { + x++; + } else { + x++; + y--; } - - return ans; + } } + return ans; + } } diff --git a/Medium/Diameter of N-ary Tree.java b/Medium/Diameter of N-ary Tree.java index 96ac97a5..7bf358a5 100644 --- a/Medium/Diameter of N-ary Tree.java +++ b/Medium/Diameter of N-ary Tree.java @@ -23,28 +23,28 @@ public Node(int _val,ArrayList _children) { class Solution { public int diameter(Node root) { - int[] max = {0}; - helper(root, max); - return max[0]; + int[] diameter = {0}; + getHeight(root, diameter); + return diameter[0]; } - private int helper(Node root, int[] max) { - if (root == null) { + private int getHeight(Node node, int[] diameter) { + if (node.children.size() == 0) { return 0; } - int max1 = 0; - int max2 = 0; - for (Node child : root.children) { - int height = helper(child, max); - if (max1 < height) { - max2 = max1; - max1 = height; - } - else if (max2 < height) { - max2 = height; + int maxHeightOne = 0; + int maxHeightTwo = 0; + for (Node child : node.children) { + int parentHeight = getHeight(child, diameter) + 1; + if (parentHeight > maxHeightOne) { + maxHeightTwo = maxHeightOne; + maxHeightOne = parentHeight; + } else if (parentHeight > maxHeightTwo) { + maxHeightTwo = parentHeight; } + int currentDiameter = maxHeightOne + maxHeightTwo; + diameter[0] = Math.max(diameter[0], currentDiameter); } - max[0] = Math.max(max[0], max1 + max2); - return max1 + 1; + return maxHeightOne; } } diff --git a/Medium/Difference Between Ones and Zeros in Row and Column.java b/Medium/Difference Between Ones and Zeros in Row and Column.java new file mode 100644 index 00000000..641b0b38 --- /dev/null +++ b/Medium/Difference Between Ones and Zeros in Row and Column.java @@ -0,0 +1,23 @@ +class Solution { + public int[][] onesMinusZeros(int[][] grid) { + int rows = grid.length; + int cols = grid[0].length; + int[][] rowCount = new int[rows][2]; + int[][] colCount = new int[cols][2]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + rowCount[i][0] += grid[i][j] == 1 ? 1 : 0; + rowCount[i][1] += grid[i][j] != 1 ? 1 : 0; + colCount[j][0] += grid[i][j] == 1 ? 1 : 0; + colCount[j][1] += grid[i][j] != 1 ? 1 : 0; + } + } + int[][] result = new int[rows][cols]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + result[i][j] = rowCount[i][0] + colCount[j][0] - rowCount[i][1] - colCount[j][1]; + } + } + return result; + } +} diff --git a/Medium/Different Ways to Add Parentheses.java b/Medium/Different Ways to Add Parentheses.java new file mode 100644 index 00000000..706fcf6c --- /dev/null +++ b/Medium/Different Ways to Add Parentheses.java @@ -0,0 +1,42 @@ +class Solution { + public List diffWaysToCompute(String expression) { + List result = new ArrayList<>(); + if (expression.length() == 0) { + return result; + } + if (expression.length() == 1) { + result.add(Integer.parseInt(expression)); + return result; + } + if (expression.length() == 2 && Character.isDigit(expression.charAt(0))) { + result.add(Integer.parseInt(expression)); + return result; + } + for (int i = 0; i < expression.length(); i++) { + char c = expression.charAt(i); + if (Character.isDigit(c)) { + continue; + } + List leftResult = diffWaysToCompute(expression.substring(0, i)); + List rightResult = diffWaysToCompute(expression.substring(i + 1)); + for (int leftVal : leftResult) { + for (int rightVal : rightResult) { + int value = 0; + switch(c) { + case '+': + value = leftVal + rightVal; + break; + case '-': + value = leftVal - rightVal; + break; + case '*': + value = leftVal * rightVal; + break; + } + result.add(value); + } + } + } + return result; + } +} diff --git a/Medium/Distribute Candies Among Children II.java b/Medium/Distribute Candies Among Children II.java new file mode 100644 index 00000000..aa9648f2 --- /dev/null +++ b/Medium/Distribute Candies Among Children II.java @@ -0,0 +1,14 @@ +class Solution { + public long distributeCandies(int n, int limit) { + long result = 0; + for (int i = 0; i <= Math.min(limit, n); i++) { + // distribution not possible as we will have to allocate at least one child with + // more than limit candies + if (n - i > 2 * limit) { + continue; + } + result += Math.min(n - i, limit) - Math.max(0, n - i - limit) + 1; + } + return result; + } +} diff --git a/Medium/Divide Array Into Arrays With Max Difference.java b/Medium/Divide Array Into Arrays With Max Difference.java new file mode 100644 index 00000000..77959768 --- /dev/null +++ b/Medium/Divide Array Into Arrays With Max Difference.java @@ -0,0 +1,15 @@ +class Solution { + public int[][] divideArray(int[] nums, int k) { + Arrays.sort(nums); + int n = nums.length; + int[][] result = new int[n / 3][3]; + int idx = 0; + for (int i = 2; i < nums.length; i += 3) { + if (nums[i] - nums[i - 2] > k) { + return new int[][]{}; + } + result[idx++] = new int[]{nums[i - 2], nums[i - 1], nums[i]}; + } + return result; + } +} diff --git a/Medium/Divide Intervals Into Minimum Number of Groups.java b/Medium/Divide Intervals Into Minimum Number of Groups.java new file mode 100644 index 00000000..b58d0dcb --- /dev/null +++ b/Medium/Divide Intervals Into Minimum Number of Groups.java @@ -0,0 +1,21 @@ +class Solution { + public int minGroups(int[][] intervals) { + Arrays.sort(intervals, (o1, o2) -> { + int c = Integer.compare(o1[0], o2[0]); + if (c == 0) { + return Integer.compare(o1[1], o2[1]); + } + return c; + }); + int max = 0; + PriorityQueue pq = new PriorityQueue<>(); + for (int[] interval : intervals) { + while (!pq.isEmpty() && pq.peek() < interval[0]) { + pq.poll(); + } + pq.add(interval[1]); + max = Math.max(max, pq.size()); + } + return max; + } +} diff --git a/Medium/Divide Players Into Teams of Equal Skill.java b/Medium/Divide Players Into Teams of Equal Skill.java new file mode 100644 index 00000000..41a5f1f7 --- /dev/null +++ b/Medium/Divide Players Into Teams of Equal Skill.java @@ -0,0 +1,25 @@ +class Solution { + public long dividePlayers(int[] skill) { + int n = skill.length; + int totalSkill = 0; + Map map = new HashMap<>(); + for (int s : skill) { + totalSkill += s; + map.put(s, map.getOrDefault(s, 0) + 1); + } + if (totalSkill % (n / 2) != 0) { + return -1; + } + int targetSkill = totalSkill / (n / 2); + long totalChemistry = 0; + for (int currSkill : map.keySet()) { + int partnerSkill = targetSkill - currSkill; + int currSkillFreq = map.get(currSkill); + if (!map.containsKey(partnerSkill) || currSkillFreq != map.get(partnerSkill)) { + return -1; + } + totalChemistry += (long) currSkill * (long) partnerSkill * (long) currSkillFreq; + } + return totalChemistry / 2; + } +} diff --git a/Medium/Dot Product of Two Sparse Vectors.java b/Medium/Dot Product of Two Sparse Vectors.java index 92fed72b..824c407f 100644 --- a/Medium/Dot Product of Two Sparse Vectors.java +++ b/Medium/Dot Product of Two Sparse Vectors.java @@ -1,38 +1,32 @@ class SparseVector { - Map map; - int[] nums; - SparseVector(int[] nums) { - this.nums = nums; - } - private Map getMap() { - if (map != null) { - return map; - } - map = new HashMap<>(); + private Map nonZeroRowMap; + + SparseVector(int[] nums) { + this.nonZeroRowMap = new HashMap<>(); for (int i = 0; i < nums.length; i++) { if (nums[i] != 0) { - map.put(i, nums[i]); + nonZeroRowMap.put(i, nums[i]); } } - return map; } - // Return the dotProduct of two sparse vectors +// Return the dotProduct of two sparse vectors public int dotProduct(SparseVector vec) { - Map vecMap = vec.getMap(); - Map map = getMap(); - return map.size() > vecMap.size() ? helper(vecMap, map) : helper(map, vecMap); + Map vecNonZeroRowMap = vec.getNonZeroRowMap(); + return this.nonZeroRowMap.size() < vecNonZeroRowMap.size() ? dotProductHelper(this.nonZeroRowMap, vecNonZeroRowMap) : dotProductHelper(vecNonZeroRowMap, this.nonZeroRowMap); } - private int helper(Map map1, Map map2) { - int val = 0; - for (Integer key : map1.keySet()) { - if (map2.containsKey(key)) { - val += map1.get(key) * map2.get(key); - } + private int dotProductHelper(Map mapOne, Map mapTwo) { + int product = 0; + for (Integer key : mapOne.keySet()) { + product += mapOne.get(key) * mapTwo.getOrDefault(key, 0); } - return val; + return product; + } + + public Map getNonZeroRowMap() { + return new HashMap<>(nonZeroRowMap); } } diff --git a/Medium/Dota2 Senate.java b/Medium/Dota2 Senate.java new file mode 100644 index 00000000..56465cb4 --- /dev/null +++ b/Medium/Dota2 Senate.java @@ -0,0 +1,24 @@ +class Solution { + public String predictPartyVictory(String senate) { + int n = senate.length(); + Queue rValid = new LinkedList<>(); + Queue dValid = new LinkedList<>(); + for (int i = 0; i < n; i++) { + if (senate.charAt(i) == 'R') { + rValid.add(i); + } else { + dValid.add(i); + } + } + while (!rValid.isEmpty() && !dValid.isEmpty()) { + int rTurn = rValid.remove(); + int dTurn = dValid.remove(); + if (dTurn < rTurn) { + dValid.add(dTurn + n); + } else { + rValid.add(rTurn + n); + } + } + return rValid.isEmpty() ? "Dire" : "Radiant"; + } +} diff --git a/Medium/Double Modular Exponentiation.java b/Medium/Double Modular Exponentiation.java new file mode 100644 index 00000000..6dada495 --- /dev/null +++ b/Medium/Double Modular Exponentiation.java @@ -0,0 +1,23 @@ +class Solution { + public List getGoodIndices(int[][] variables, int target) { + List result = new ArrayList<>(); + for (int i = 0; i < variables.length; i++) { + int a = variables[i][0]; + int b = variables[i][1]; + int c = variables[i][2]; + int m = variables[i][3]; + int base = 1; + for (int j = 0; j < b; j++) { + base = (base * a) % 10; + } + int value = 1; + for (int j = 0; j < c; j++) { + value = (value * base) % m; + } + if (value == target) { + result.add(i); + } + } + return result; + } +} diff --git a/Medium/Double a Number Represented as a Linked List.java b/Medium/Double a Number Represented as a Linked List.java new file mode 100644 index 00000000..9e2bcbaa --- /dev/null +++ b/Medium/Double a Number Represented as a Linked List.java @@ -0,0 +1,40 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode doubleIt(ListNode head) { + ListNode rev = reverse(head); + ListNode curr = rev; + int carry = 0; + while (curr != null) { + int val = curr.val * 2 + carry; + carry = val / 10; + curr.val = val % 10; + if (curr.next == null && carry != 0) { + curr.next = new ListNode(carry); + break; + } + curr = curr.next; + } + return reverse(rev); + } + + private ListNode reverse(ListNode curr) { + ListNode next = null; + ListNode prev = null; + while (curr != null) { + next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + return prev; + } +} diff --git a/Medium/Encode and Decode Strings.java b/Medium/Encode and Decode Strings.java index ec923b8f..c39d5b6a 100644 --- a/Medium/Encode and Decode Strings.java +++ b/Medium/Encode and Decode Strings.java @@ -3,8 +3,8 @@ public class Codec { // Encodes a list of strings to a single string. public String encode(List strs) { StringBuilder sb = new StringBuilder(); - for (String str : strs) { - sb.append(lengthEncode(str)).append(str); + for (String s : strs) { + sb.append(lengthEncoding(s)).append(s); } return sb.toString(); } @@ -12,24 +12,34 @@ public String encode(List strs) { // Decodes a single string to a list of strings. public List decode(String s) { int idx = 0; + List result = new ArrayList<>(); int n = s.length(); - List list = new ArrayList<>(); while (idx < n) { - int length = Integer.parseInt(s.substring(idx, idx + 10)); - idx += 10; - list.add(s.substring(idx, idx + length)); - idx += length; + int currStringLength = lengthDecoding(s.substring(idx, idx + 4)); + idx += 4; + result.add(s.substring(idx, idx + currStringLength)); + idx += currStringLength; } - return list; + return result; } - private String lengthEncode(String s) { + private String lengthEncoding(String s) { int n = s.length(); - return String.join("", Collections.nCopies(10 - String.valueOf(n).length(), "0")) + String.valueOf(n); + char[] bytes = new char[4]; + for(int i = 3; i >= 0; i--) { + bytes[3 - i] = (char) (n >> (i * 8) & 0xff); + } + return new String(bytes); + } + + private int lengthDecoding(String bytesStr) { + int result = 0; + for(char b : bytesStr.toCharArray()) + result = (result << 8) + (int)b; + return result; } } // Your Codec object will be instantiated and called as such: // Codec codec = new Codec(); // codec.decode(codec.encode(strs)); - diff --git a/Medium/Equal Row and Column Pairs.java b/Medium/Equal Row and Column Pairs.java new file mode 100644 index 00000000..515fb2db --- /dev/null +++ b/Medium/Equal Row and Column Pairs.java @@ -0,0 +1,23 @@ +class Solution { + public int equalPairs(int[][] grid) { + Map rowMap = new HashMap<>(); + for (int[] value : grid) { + StringBuilder sb = new StringBuilder(); + for (int j = 0; j < grid[0].length; j++) { + sb.append(value[j]).append("|"); + } + String key = sb.toString(); + rowMap.put(key, rowMap.getOrDefault(key, 0) + 1); + } + int count = 0; + for (int i = 0; i < grid[0].length; i++) { + StringBuilder sb = new StringBuilder(); + for (int[] ints : grid) { + sb.append(ints[i]).append("|"); + } + String key = sb.toString(); + count += rowMap.getOrDefault(key, 0); + } + return count; + } +} diff --git a/Medium/Evaluate Reverse Polish Notation.java b/Medium/Evaluate Reverse Polish Notation.java index 8b606b68..17b3a709 100644 --- a/Medium/Evaluate Reverse Polish Notation.java +++ b/Medium/Evaluate Reverse Polish Notation.java @@ -1,31 +1,26 @@ class Solution { + + private static final Set OPERATIONS = Set.of("*", "+", "/", "-"); + public int evalRPN(String[] tokens) { Stack stack = new Stack<>(); - Set operations = new HashSet<>(Arrays.asList("-", "+", "*", "/")); for (String token : tokens) { - if (operations.contains(token)) { - int num1 = stack.pop(); - int num2 = stack.pop(); - stack.push(performOperation(num2, num1, token)); - } - else { + if (OPERATIONS.contains(token)) { + stack.push(performOperation(stack.pop(), stack.pop(), token)); + } else { stack.push(Integer.parseInt(token)); } } - return stack.pop(); } - private int performOperation(int a, int b, String operation) { - switch(operation) { - case "+": - return a + b; - case "-": - return a - b; - case "*": - return a * b; - default: - return a / b; - } + private static int performOperation(int num2, int num1, String operation) throws UnsupportedOperationException { + return switch(operation) { + case "+" -> num1 + num2; + case "-" -> num1 - num2; + case "*" -> num1 * num2; + case "/" -> num1 / num2; + default -> throw new UnsupportedOperationException("Operation not supported"); + }; } } diff --git a/Medium/Evaluate the Bracket Pairs of a String.java b/Medium/Evaluate the Bracket Pairs of a String.java new file mode 100644 index 00000000..3a90861a --- /dev/null +++ b/Medium/Evaluate the Bracket Pairs of a String.java @@ -0,0 +1,24 @@ +class Solution { + public String evaluate(String s, List> knowledge) { + Map map = new HashMap<>(); + for (List entry : knowledge) { + map.put(entry.get(0), entry.get(1)); + } + StringBuilder sb = new StringBuilder(); + int idx = 0; + int n = s.length(); + while (idx < n) { + if (s.charAt(idx) == '(') { + idx++; + int currIdx = idx; + while (idx < n && s.charAt(idx) != ')') { + idx++; + } + sb.append(map.getOrDefault(s.substring(currIdx, idx++), "?")); + } else { + sb.append(s.charAt(idx++)); + } + } + return sb.toString(); + } +} diff --git a/Medium/Even Odd Tree.java b/Medium/Even Odd Tree.java index 0d3a4886..574ddf6b 100644 --- a/Medium/Even Odd Tree.java +++ b/Medium/Even Odd Tree.java @@ -14,36 +14,31 @@ * } */ class Solution { - public boolean isEvenOddTree(TreeNode root) { - Queue queue = new LinkedList<>(); - queue.add(root); - int remainderExpected = 1; - while (!queue.isEmpty()) { - int size = queue.size(); - Integer prev = null; - while (size-- > 0) { - TreeNode removed = queue.remove(); - if (removed.val % 2 != remainderExpected) { - return false; + public boolean isEvenOddTree(TreeNode root) { + Queue queue = new LinkedList<>(); + queue.add(root); + boolean even = true; + while (!queue.isEmpty()) { + int size = queue.size(); + int prev = even ? Integer.MIN_VALUE : Integer.MAX_VALUE; + while (size-- > 0) { + TreeNode removed = queue.remove(); + if ((even && removed.val % 2 == 0) || (!even && removed.val % 2 != 0)) { + return false; + } + if ((even && removed.val <= prev) || (!even && removed.val >= prev)) { + return false; + } + prev = removed.val; + if (removed.left != null) { + queue.add(removed.left); + } + if (removed.right != null) { + queue.add(removed.right); + } + } + even = !even; } - if (prev != null) { - if (remainderExpected == 1 && removed.val <= prev) { - return false; - } - if (remainderExpected == 0 && removed.val >= prev) { - return false; - } - } - prev = removed.val; - if (removed.left != null) { - queue.add(removed.left); - } - if (removed.right != null) { - queue.add(removed.right); - } - } - remainderExpected = remainderExpected == 1 ? 0 : 1; + return true; } - return true; - } } diff --git a/Medium/Exclusive Time of Functions.java b/Medium/Exclusive Time of Functions.java index 0138ec69..cd85e84c 100644 --- a/Medium/Exclusive Time of Functions.java +++ b/Medium/Exclusive Time of Functions.java @@ -1,28 +1,25 @@ class Solution { public int[] exclusiveTime(int n, List logs) { - int[] timer = new int[n]; Stack stack = new Stack<>(); - int lastTime = 0;; - + int[] result = new int[n]; + int lastTimestamp = 0; for (String log : logs) { - String[] strs = log.split(":"); - int id = Integer.parseInt(strs[0]); - String status = strs[1]; - int time = Integer.parseInt(strs[2]); - - if (!stack.isEmpty()) { - timer[stack.peek()] += time - lastTime; - } - lastTime = time; - if (status.equals("start")) { + String[] split = log.split(":"); + int id = Integer.parseInt(split[0]); + int timestamp = Integer.parseInt(split[2]); + if (split[1].equals("start")) { + // We consider timestamp as part of current computation + if (!stack.isEmpty()) { + result[stack.peek()] += timestamp - lastTimestamp; + } stack.push(id); - } - else { - timer[stack.pop()]++; - lastTime++; + lastTimestamp = timestamp; + } else { + // We consider timestamp as part of previous computation + result[stack.pop()] += timestamp - lastTimestamp + 1; + lastTimestamp = timestamp + 1; } } - - return timer; + return result; } } diff --git a/Medium/Execution of All Suffix Instructions Staying in a Grid.java b/Medium/Execution of All Suffix Instructions Staying in a Grid.java new file mode 100644 index 00000000..4d231f93 --- /dev/null +++ b/Medium/Execution of All Suffix Instructions Staying in a Grid.java @@ -0,0 +1,25 @@ +class Solution { + public int[] executeInstructions(int n, int[] startPos, String s) { + int[] result = new int[s.length()]; + Map directionToMovementMap = Map.of( + 'R', new int[]{0, 1}, + 'L', new int[]{0, -1}, + 'U', new int[]{-1, 0}, + 'D', new int[]{1, 0} + ); + for (int i = 0; i < s.length(); i++) { + int startX = startPos[0]; + int startY = startPos[1]; + int j = i; + for (; j < s.length(); j++) { + startX += directionToMovementMap.get(s.charAt(j))[0]; + startY += directionToMovementMap.get(s.charAt(j))[1]; + if (startX < 0 || startY < 0 || startX >= n || startY >= n) { + break; + } + } + result[i] = j - i; + } + return result; + } +} diff --git a/Medium/Expressive Words.java b/Medium/Expressive Words.java index b9b70e1e..2903acba 100644 --- a/Medium/Expressive Words.java +++ b/Medium/Expressive Words.java @@ -1,47 +1,32 @@ class Solution { - public int expressiveWords(String S, String[] words) { - int count = 0; - char[] sChar = S.toCharArray(); - for (String word : words) { - char[] wChar = word.toCharArray(); - if (check(sChar, wChar)) { - count++; - } - } - - return count; - } - - private boolean check(char[] s, char[] w) { - int i = 0; - int j = 0; - - while (i < s.length && j < w.length) { - if (s[i] != w[j]) { - return false; - } - - int tempI = i; - int tempJ = j; - - while (i < s.length && s[i] == s[tempI]) { - i++; - } - - while (j < w.length && w[j] == w[tempJ]) { - j++; - } - - int l1 = i - tempI; - int l2 = j - tempJ; - - if (l1 == l2 || l1 >= 3 && l1 > l2) { - continue; - } - - return false; - } - - return i == s.length && j == w.length; + public int expressiveWords(String s, String[] words) { + return (int) Arrays.stream(words).filter(word -> isExpressive(s, word)).count(); + } + + private boolean isExpressive(String s, String word) { + int sIdx = 0; + int wordIdx = 0; + while (sIdx < s.length() && wordIdx < word.length()) { + if (s.charAt(sIdx) != word.charAt(wordIdx)) { + return false; + } + char c1 = s.charAt(sIdx); + int countC1 = 0; + while (sIdx < s.length() && s.charAt(sIdx) == c1) { + sIdx++; + countC1++; + } + char c2 = word.charAt(wordIdx); + int countC2 = 0; + while (wordIdx < word.length() && word.charAt(wordIdx) == c2) { + wordIdx++; + countC2++; + } + if (countC1 == countC2 || (countC1 > countC2 && countC1 >= 3)) { + continue; + } + return false; } + return sIdx == s.length() && wordIdx == word.length(); + } } diff --git a/Medium/Extra Characters in a String.java b/Medium/Extra Characters in a String.java new file mode 100644 index 00000000..4d43cc5c --- /dev/null +++ b/Medium/Extra Characters in a String.java @@ -0,0 +1,25 @@ +class Solution { + public int minExtraChar(String s, String[] dictionary) { + Integer[] dp = new Integer[s.length() + 1]; + return helper(0, s, Arrays.stream(dictionary).collect(Collectors.toSet()), dp); + } + + private int helper(int idx, String s, Set set, Integer[] dp) { + if (idx == s.length()) { + return 0; + } + if (dp[idx] != null) { + return dp[idx]; + } + int result = Integer.MAX_VALUE; + for (int i = idx; i < s.length(); i++) { + String sub = s.substring(idx, i + 1); + if (set.contains(sub)) { + result = Math.min(result, helper(i + 1, s, set, dp)); + } else { + result = Math.min(result, i - idx + 1 + helper(i + 1, s, set, dp)); + } + } + return dp[idx] = result; + } +} diff --git a/Medium/Fair Distribution of Cookies.java b/Medium/Fair Distribution of Cookies.java new file mode 100644 index 00000000..ad4b0f94 --- /dev/null +++ b/Medium/Fair Distribution of Cookies.java @@ -0,0 +1,23 @@ +class Solution { + public int distributeCookies(int[] cookies, int k) { + int[] share = new int[k]; + return helper(cookies, share, 0); + } + + private int helper(int[] cookies, int[] share, int idx) { + if (idx == cookies.length) { + int maxShare = share[0]; + for (int s : share) { + maxShare = Math.max(s, maxShare); + } + return maxShare; + } + int result = Integer.MAX_VALUE; + for(int i = 0; i < share.length; i++){ + share[i] += cookies[idx]; + result = Math.min(result, helper(cookies, share, idx + 1)); + share[i] -= cookies[idx]; + } + return result; + } +} diff --git a/Medium/Find All Anagrams in a String.java b/Medium/Find All Anagrams in a String.java index 1edba8c7..e18917da 100644 --- a/Medium/Find All Anagrams in a String.java +++ b/Medium/Find All Anagrams in a String.java @@ -1,30 +1,24 @@ class Solution { - public List findAnagrams(String s, String p) { - List list = new ArrayList<>(); - if (s.length() < p.length()) { - return list; + public List findAnagrams(String s, String p) { + if (s.length() < p.length()) { + return new ArrayList<>(); + } + List result = new ArrayList<>(); + int[] patternCounter = new int[26]; + for (char c : p.toCharArray()) { + patternCounter[c - 'a']++; + } + int[] counter = new int[26]; + int start = 0; + for (int i = 0; i < s.length(); i++) { + counter[s.charAt(i) - 'a']++; + if (i >= p.length() - 1) { + if (Arrays.equals(patternCounter, counter)) { + result.add(start); + } + counter[s.charAt(start++) - 'a']--; + } + } + return result; } - int[] pArr = new int[26]; - for (char c : p.toCharArray()) { - pArr[c - 'a']++; - } - String pStr = Arrays.toString(pArr); - int start = 0; - int end = 0; - int n = s.length(); - int[] sArr = new int[26]; - while (end < (p.length() - 1)) { - sArr[s.charAt(end) - 'a']++; - end++; - } - while (end < n) { - sArr[s.charAt(end) - 'a']++; - end++; - if (Arrays.toString(sArr).equals(pStr)) { - list.add(start); - } - sArr[s.charAt(start++) - 'a']--; - } - return list; - } } diff --git a/Medium/Find All Groups of Farmland.java b/Medium/Find All Groups of Farmland.java new file mode 100644 index 00000000..130db6a1 --- /dev/null +++ b/Medium/Find All Groups of Farmland.java @@ -0,0 +1,49 @@ +class Solution { + + private static final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + + public int[][] findFarmland(int[][] land) { + int rows = land.length; + int cols = land[0].length; + boolean[][] visited = new boolean[rows][cols]; + List result = new ArrayList<>(); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (land[i][j] == 1 && !visited[i][j]) { + traverse(land, i, j, visited, result); + } + } + } + return result.stream() + .map(int[]::clone) + .toArray(int[][]::new); + } + + private static void traverse(int[][] land, int i, int j, boolean[][] visited, List result) { + int rows = land.length; + int cols = land[0].length; + Queue queue = new LinkedList<>(); + int[] leftMost = {i, j}; + int[] rightMost = {i, j}; + queue.add(new int[]{i, j}); + visited[i][j] = true; + while (!queue.isEmpty()) { + int[] removed = queue.remove(); + int x = removed[0]; + int y = removed[1]; + leftMost[0] = Math.min(leftMost[0], x); + leftMost[1] = Math.min(leftMost[1], y); + rightMost[0] = Math.max(rightMost[0], x); + rightMost[1] = Math.max(rightMost[1], y); + for (int[] dir : DIRS) { + int newX = x + dir[0]; + int newY = y + dir[1]; + if (newX >= 0 && newY >= 0 && newX < rows && newY < cols && !visited[newX][newY] && land[newX][newY] == 1) { + queue.add(new int[]{newX, newY}); + visited[newX][newY] = true; + } + } + } + result.add(new int[]{leftMost[0], leftMost[1], rightMost[0], rightMost[1]}); + } +} diff --git a/Medium/Find All Lonely Numbers in the Array.java b/Medium/Find All Lonely Numbers in the Array.java new file mode 100644 index 00000000..c55981d5 --- /dev/null +++ b/Medium/Find All Lonely Numbers in the Array.java @@ -0,0 +1,16 @@ +import java.util.Map.Entry; + + +class Solution { + public List findLonely(int[] nums) { + Map map = Arrays.stream(nums) + .boxed() + .collect(Collectors.groupingBy(Function.identity(), HashMap::new, Collectors.counting())); + return map.entrySet().stream() + .filter( + entry -> entry.getValue().equals(1L) && !map.containsKey(entry.getKey() + 1) + && !map.containsKey(entry.getKey() - 1)) + .map(Entry::getKey) + .collect(Collectors.toList()); + } +} diff --git a/Medium/Find All Possible Recipes from Given Supplies.java b/Medium/Find All Possible Recipes from Given Supplies.java new file mode 100644 index 00000000..702d1d15 --- /dev/null +++ b/Medium/Find All Possible Recipes from Given Supplies.java @@ -0,0 +1,29 @@ +class Solution { + public List findAllRecipes(String[] recipes, List> ingredients, String[] supplies) { + Map> map = new HashMap<>(); + Map ingredientCounter = new HashMap<>(); + for (int i = 0; i < recipes.length; i++) { + List currentIngredientList = ingredients.get(i); + for (String ingredient : currentIngredientList) { + map.computeIfAbsent(ingredient, k -> new ArrayList<>()).add(recipes[i]); + ingredientCounter.put(recipes[i], ingredientCounter.getOrDefault(recipes[i], 0) + 1); + } + } + Queue queue = new LinkedList<>(); + Set prepared = new HashSet<>(); + for (String supply : supplies) { + queue.add(supply); + } + while (!queue.isEmpty()) { + String removed = queue.remove(); + for (String dependentRecipe : map.getOrDefault(removed, new ArrayList<>())) { + ingredientCounter.put(dependentRecipe, ingredientCounter.getOrDefault(dependentRecipe, 0) - 1); + if (ingredientCounter.get(dependentRecipe) == 0) { + queue.add(dependentRecipe); + prepared.add(dependentRecipe); + } + } + } + return new ArrayList<>(prepared); + } +} diff --git a/Medium/Find Center of Star Graph.java b/Medium/Find Center of Star Graph.java new file mode 100644 index 00000000..8270ad2d --- /dev/null +++ b/Medium/Find Center of Star Graph.java @@ -0,0 +1,16 @@ +class Solution { + public int findCenter(int[][] edges) { + Map map = new HashMap<>(); + int n = edges.length; + for (int[] edge : edges) { + map.put(edge[0], map.getOrDefault(edge[0], 0) + 1); + map.put(edge[1], map.getOrDefault(edge[1], 0) + 1); + } + for (Integer key : map.keySet()) { + if (map.get(key) == n) { + return key; + } + } + return -1; + } +} diff --git a/Medium/Find Closest Node to Given Two Nodes.java b/Medium/Find Closest Node to Given Two Nodes.java new file mode 100644 index 00000000..4c68c333 --- /dev/null +++ b/Medium/Find Closest Node to Given Two Nodes.java @@ -0,0 +1,40 @@ +class Solution { + public int closestMeetingNode(int[] edges, int node1, int node2) { + int n = edges.length; + int[] distance1 = new int[n]; + int[] distance2 = new int[n]; + Arrays.fill(distance1, Integer.MAX_VALUE); + Arrays.fill(distance2, Integer.MAX_VALUE); + bfs(node1, edges, distance1); + bfs(node2, edges, distance2); + int minDistanceNode = -1; + int currMinDistance = Integer.MAX_VALUE; + for (int i = 0; i < n; i++) { + if (currMinDistance > Math.max(distance1[i], distance2[i])) { + minDistanceNode = i; + currMinDistance = Math.max(distance1[i], distance2[i]); + } + } + return minDistanceNode; + } + + private void bfs(int startNode, int[] edges, int[] distance) { + int n = edges.length; + Queue queue = new LinkedList<>(); + queue.add(startNode); + boolean[] visited = new boolean[n]; + distance[startNode] = 0; + while (!queue.isEmpty()) { + int node = queue.remove(); + if (visited[node]) { + continue; + } + visited[node] = true; + int neighbor = edges[node]; + if (neighbor != -1 && !visited[neighbor]) { + distance[neighbor] = 1 + distance[node]; + queue.add(neighbor); + } + } + } +} diff --git a/Medium/Find Consecutive Integers from a Data Stream.java b/Medium/Find Consecutive Integers from a Data Stream.java new file mode 100644 index 00000000..7f57b28d --- /dev/null +++ b/Medium/Find Consecutive Integers from a Data Stream.java @@ -0,0 +1,23 @@ +class DataStream { + + private int k; + private int value; + private int counter; + + public DataStream(int value, int k) { + this.k = k; + this.value = value; + this.counter = 0; + } + + public boolean consec(int num) { + counter = value == num ? (counter + 1) : 0; + return counter >= k; + } +} + +/** + * Your DataStream object will be instantiated and called as such: + * DataStream obj = new DataStream(value, k); + * boolean param_1 = obj.consec(num); + */ diff --git a/Medium/Find Distance in a Binary Tree.java b/Medium/Find Distance in a Binary Tree.java new file mode 100644 index 00000000..403e1190 --- /dev/null +++ b/Medium/Find Distance in a Binary Tree.java @@ -0,0 +1,51 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public int findDistance(TreeNode root, int p, int q) { + if (p == q) { + return 0; + } + int[] result = {-1}; + dfs(root, p, q, result); + return result[0]; + } + + private int dfs(TreeNode root, int p, int q, int[] result) { + if (root == null) { + return -1; + } + int left = dfs(root.left, p, q, result); + int right = dfs(root.right, p, q, result); + if (root.val == p || root.val == q) { + if (left < 0 && right < 0) { + return 0; + } + result[0] = 1 + (left >= 0 ? left : right); + return -1; + } + if (left >= 0 && right >= 0) { + result[0] = left + right + 2; + return -1; + } + if (left >= 0) { + return left + 1; + } + if (right >= 0) { + return right + 1; + } + return -1; + } +} diff --git a/Medium/Find Duplicate File in System.java b/Medium/Find Duplicate File in System.java index 6570d540..8aa53097 100644 --- a/Medium/Find Duplicate File in System.java +++ b/Medium/Find Duplicate File in System.java @@ -1,22 +1,20 @@ class Solution { public List> findDuplicate(String[] paths) { - Map> map = new HashMap<>(); + Map> contentToDirectoryMapping = new HashMap<>(); for (String path : paths) { - String[] strs = path.split("\\s+"); - String filePath = strs[0]; - for (int i = 1; i < strs.length; i++) { - int startIdx = strs[i].indexOf('('); - String fileName = strs[i].substring(0, startIdx); - String content = strs[i].substring(startIdx, strs[i].length()); - map.computeIfAbsent(content, k -> new ArrayList<>()).add(filePath + "/" + fileName); + String[] splits = path.split("\\s+"); + String directoryName = splits[0]; + for (int i = 1; i < splits.length; i++) { + int contentStartIdx = splits[i].indexOf('('); + String fileName = splits[i].substring(0, contentStartIdx); + String content = splits[i].substring(contentStartIdx + 1, splits[i].length() - 1); + contentToDirectoryMapping.computeIfAbsent(content, k -> new HashSet<>()) + .add(directoryName + "/" + fileName); } } - List> duplicateFiles = new ArrayList<>(); - for (String key : map.keySet()) { - if (map.get(key).size() > 1) { - duplicateFiles.add(map.get(key)); - } - } - return duplicateFiles; + return contentToDirectoryMapping.values().stream() + .filter(e -> e.size() > 1) + .map(ArrayList::new) + .collect(Collectors.toList()); } } diff --git a/Medium/Find Duplicate Subtrees.java b/Medium/Find Duplicate Subtrees.java index b81a4bec..4800644b 100644 --- a/Medium/Find Duplicate Subtrees.java +++ b/Medium/Find Duplicate Subtrees.java @@ -4,35 +4,32 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - Map map; - public List findDuplicateSubtrees(TreeNode root) { - map = new HashMap<>(); - List ans = new ArrayList<>(); - - helper(root); - - for (TreeNode node : map.values()) { - if (node != null) { - ans.add(node); - } - } - - return ans; + List result = new LinkedList<>(); + traverse(root, new HashMap<>(), result); + return result; } - - private String helper(TreeNode root) { - if (root == null) { - return "#"; + + private String traverse(TreeNode node, Map frequencyMap, List result) { + if (node == null) { + return ""; + } + String key = ("(" + traverse(node.left, frequencyMap, result) + ")" + node.val + + "(" + traverse(node.right, frequencyMap, result) + ")"); + frequencyMap.put(key, frequencyMap.getOrDefault(key, 0) + 1); + if (frequencyMap.get(key) == 2) { + result.add(node); } - - String path = root.val + "|" + helper(root.left) + "|" + helper(root.right); - map.put(path, map.containsKey(path) ? root : null); - - return path; + return key; } } diff --git a/Medium/Find Elements in a Contaminated Binary Tree.java b/Medium/Find Elements in a Contaminated Binary Tree.java index 2015bd92..9048fbd2 100644 --- a/Medium/Find Elements in a Contaminated Binary Tree.java +++ b/Medium/Find Elements in a Contaminated Binary Tree.java @@ -4,30 +4,36 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class FindElements { - TreeNode root; - Set set; - public FindElements(TreeNode root) { - set = new HashSet<>(); - buildTree(root, 0); - } - - private void buildTree(TreeNode root, int val) { - if (root == null) { - return; - } - root.val = val; - set.add(val); - buildTree(root.left, 2 * val + 1); - buildTree(root.right, 2 * val + 2); - } - - public boolean find(int target) { - return set.contains(target); + + private Set set; + + public FindElements(TreeNode root) { + set = new HashSet<>(); + recover(root, 0); + } + + private void recover(TreeNode root, int value) { + if (root == null) { + return; } + set.add(value); + recover(root.left, 2 * value + 1); + recover(root.right, 2 * value + 2); + } + + public boolean find(int target) { + return set.contains(target); + } } /** diff --git a/Medium/Find Eventual Safe States.java b/Medium/Find Eventual Safe States.java new file mode 100644 index 00000000..2948587d --- /dev/null +++ b/Medium/Find Eventual Safe States.java @@ -0,0 +1,35 @@ +class Solution { + public List eventualSafeNodes(int[][] graph) { + int n = graph.length; + Map> map = new HashMap<>(); + int[] indegree = new int[n]; + for (int i = 0; i < n; i++) { + for (Integer conn : graph[i]) { + indegree[i]++; + map.computeIfAbsent(conn, k -> new HashSet<>()).add(i); + } + } + Queue queue = new LinkedList<>(); + for (int i = 0; i < n; i++) { + if (indegree[i] == 0) { + queue.add(i); + } + } + List result = new ArrayList<>(); + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + int removed = queue.remove(); + result.add(removed); + for (Integer conn : map.getOrDefault(removed, new HashSet<>())) { + indegree[conn]--; + if (indegree[conn] == 0) { + queue.add(conn); + } + } + } + } + Collections.sort(result); + return result; + } +} diff --git a/Medium/Find First and Last Position of Element in Sorted Array.java b/Medium/Find First and Last Position of Element in Sorted Array.java index 2d9e263a..64e4ecec 100644 --- a/Medium/Find First and Last Position of Element in Sorted Array.java +++ b/Medium/Find First and Last Position of Element in Sorted Array.java @@ -1,30 +1,35 @@ class Solution { - public int[] searchRange(int[] nums, int target) { - return new int[]{binarySearchHelper(nums, target, -1), binarySearchHelper(nums, target, 1)}; - } - - private int binarySearchHelper(int[] nums, int target, int dir) { - int start = 0; - int end = nums.length - 1; - int idx = -1; - while (start <= end) { - int mid = (start + end) / 2; - if (nums[mid] == target) { - idx = mid; - if (dir == -1) { - end = mid - 1; - } - else { - start = mid + 1; + + private static enum Position { + FIRST, LAST; + } + + public int[] searchRange(int[] nums, int target) { + return new int[]{ + search(nums, target, Position.FIRST), + search(nums, target, Position.LAST) + }; + } + + private static int search(int[] nums, int target, Position position) { + int left = 0; + int right = nums.length - 1; + int idx = -1; + while (left <= right) { + int mid = (left + right) / 2; + if (nums[mid] == target) { + idx = mid; + if (position == Position.FIRST) { + right = mid - 1; + } else { + left = mid + 1; + } + } else if (nums[mid] > target) { + right = mid - 1; + } else { + left = mid + 1; + } } - } - else if (nums[mid] < target) { - start = mid + 1; - } - else { - end = mid - 1; - } + return idx; } - return idx; - } } diff --git a/Medium/Find K Closest Elements.java b/Medium/Find K Closest Elements.java index 76a292bb..eeddacba 100644 --- a/Medium/Find K Closest Elements.java +++ b/Medium/Find K Closest Elements.java @@ -1,41 +1,38 @@ class Solution { public List findClosestElements(int[] arr, int k, int x) { - if (k == 0 || arr.length == 0) { - return new ArrayList<>(); - } - int[] diffArr = new int[arr.length]; - int minDiff = Integer.MAX_VALUE; - int minDiffIdx = -1; - for (int i = 0; i < arr.length; i++) { - diffArr[i] = Math.abs(arr[i] - x); - if (minDiff > diffArr[i]) { - minDiff = diffArr[i]; - minDiffIdx = i; + List result = new ArrayList<>(); + if (arr.length == k) { + for (int num : arr) { + result.add(num); } + return result; } - int left = minDiffIdx - 1; - int right = minDiffIdx + 1; - List list = new ArrayList<>(); - list.add(arr[minDiffIdx]); - k--; - while (k > 0) { - if (left >= 0 && right < arr.length) { - if (diffArr[left] <= diffArr[right]) { - list.add(arr[left--]); - } - else { - list.add(arr[right++]); - } + int left = 0; + int right = arr.length; + while (left < right) { + int mid = (left + right) / 2; + if (arr[mid] >= x) { + right = mid; + } else { + left = mid + 1; } - else if (left >= 0 && right == arr.length) { - list.add(arr[left--]); + } + left--; + right = left + 1; + while (right - left - 1 < k) { + if (left == -1) { + right++; + continue; } - else { - list.add(arr[right++]); + if (right == arr.length || Math.abs(arr[left] - x) <= Math.abs(arr[right] - x)) { + left--; + } else { + right++; } - k--; } - Collections.sort(list); - return list; + for (int i = left + 1; i < right; i++) { + result.add(arr[i]); + } + return result; } } diff --git a/Medium/Find K Pairs with Smallest Sums.java b/Medium/Find K Pairs with Smallest Sums.java index 894ca10d..f29f5c15 100644 --- a/Medium/Find K Pairs with Smallest Sums.java +++ b/Medium/Find K Pairs with Smallest Sums.java @@ -1,54 +1,26 @@ -class Solution { - public List kSmallestPairs(int[] nums1, int[] nums2, int k) { - List ans = new ArrayList<>(); - - if (nums1.length == 0 || nums2.length == 0 || k == 0) { - return ans; - } - - PriorityQueue pq = new PriorityQueue<>(new Comparator() { - @Override - public int compare(Element o1, Element o2) { - return (o1.x + o1.y) - (o2.x + o2.y); - } - }); - - for (int i=0; i> kSmallestPairs(int[] nums1, int[] nums2, int k) { + PriorityQueue pq = new PriorityQueue<>((a, b) -> a[2] - b[2]); + List> result = new ArrayList<>(); + Set> visited = new HashSet<>(); + pq.add(new int[]{0, 0, nums1[0] + nums2[0]}); + visited.add(new Pair(0, 0)); while (k-- > 0 && !pq.isEmpty()) { - Element temp = pq.poll(); - ans.add(new int[]{temp.y, temp.x}); - - if (temp.idx >= nums1.length-1) { - continue; + int[] removed = pq.poll(); + int i = removed[0]; + int j = removed[1]; + result.add(List.of(nums1[i], nums2[j])); + Pair nums1Pair = new Pair(i + 1, j); + Pair nums2Pair = new Pair(i, j + 1); + if (i + 1 < nums1.length && !visited.contains(nums1Pair)) { + pq.add(new int[]{i + 1, j, nums1[i + 1] + nums2[j]}); + visited.add(nums1Pair); + } + if (j + 1 < nums2.length && !visited.contains(nums2Pair)) { + pq.add(new int[]{i, j + 1, nums1[i] + nums2[j + 1]}); + visited.add(nums2Pair); } - - pq.offer(new Element(temp.idx+1, temp.x, nums1[temp.idx+1])); - } - - return ans; - } - - class Element { - int idx; - int x; - int y; - - public Element(int val, int x, int y) { - this.idx = val; - this.x = x; - this.y = y; - } - - @Override - public String toString() { - return "Element{" + - "idx=" + idx + - ", x=" + x + - ", y=" + y + - '}'; } + return result; } } diff --git a/Medium/Find K-Length Substrings With No Repeated Characters.java b/Medium/Find K-Length Substrings With No Repeated Characters.java index 5c435fbf..fee2952d 100644 --- a/Medium/Find K-Length Substrings With No Repeated Characters.java +++ b/Medium/Find K-Length Substrings With No Repeated Characters.java @@ -1,26 +1,24 @@ class Solution { - public int numKLenSubstrNoRepeats(String S, int K) { - int count = 0; - int start = 0; - Map map = new HashMap<>(); - for (int i = 0; i < K - 1 && i < S.length(); i++) { - map.put(S.charAt(i), map.getOrDefault(S.charAt(i), 0) + 1); - } - - for (int i = K - 1; i < S.length(); i++) { - map.put(S.charAt(i), map.getOrDefault(S.charAt(i), 0) + 1); - if (map.size() == K) { - count++; - } - - map.put(S.charAt(start), map.get(S.charAt(start)) - 1); - if (map.get(S.charAt(start)) == 0) { - map.remove(S.charAt(start)); - } - - start++; - } - - return count; + public int numKLenSubstrNoRepeats(String s, int k) { + if (s.length() < k) { + return 0; } + Map map = new HashMap<>(); + for (int i = 0; i < k; i++) { + map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1); + } + int resultCount = 0; + for (int i = k; i < s.length(); i++) { + if (map.size() == k) { + resultCount++; + } + int startIdx = i - k; + map.put(s.charAt(startIdx), map.getOrDefault(s.charAt(startIdx), 0) - 1); + if (map.get(s.charAt(startIdx)) == 0) { + map.remove(s.charAt(startIdx)); + } + map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1); + } + return resultCount + (map.size() == k ? 1 : 0); + } } diff --git a/Medium/Find Kth Bit in Nth Binary String.java b/Medium/Find Kth Bit in Nth Binary String.java new file mode 100644 index 00000000..e98b29c7 --- /dev/null +++ b/Medium/Find Kth Bit in Nth Binary String.java @@ -0,0 +1,22 @@ +class Solution { + public char findKthBit(int n, int k) { + return nthString(n).charAt(k - 1); + } + + private String nthString(int n) { + if (n == 1) { + return "0"; + } + String prevString = nthString(n - 1); + return prevString + "1" + reverseAndInvert(prevString); + } + + private String reverseAndInvert(String s) { + char[] chars = s.toCharArray(); + for (int i = 0; i < s.length(); i++) { + chars[i] = chars[i] == '1' ? '0' : '1'; + } + StringBuilder sb = new StringBuilder(String.valueOf(chars)); + return sb.reverse().toString(); + } +} diff --git a/Medium/Find Largest Value in Each Tree Row.java b/Medium/Find Largest Value in Each Tree Row.java index 49aeca0e..2f0c7883 100644 --- a/Medium/Find Largest Value in Each Tree Row.java +++ b/Medium/Find Largest Value in Each Tree Row.java @@ -4,32 +4,38 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public List largestValues(TreeNode root) { - List list = new ArrayList<>(); - if (root == null) { - return list; - } - Queue queue = new LinkedList<>(); - queue.add(root); - while (!queue.isEmpty()) { - int maxVal = Integer.MIN_VALUE; - int size = queue.size(); - while (size-- > 0) { - TreeNode removed = queue.remove(); - maxVal = Math.max(maxVal, removed.val); - if (removed.left != null) { - queue.add(removed.left); + public List largestValues(TreeNode root) { + if (root == null) { + return new ArrayList<>(); } - if (removed.right != null) { - queue.add(removed.right); + List result = new ArrayList<>(); + Queue queue = new LinkedList<>(); + queue.add(root); + while (!queue.isEmpty()) { + int size = queue.size(); + int maxValue = queue.peek().val; + while (size-- > 0) { + TreeNode removed = queue.remove(); + maxValue = Math.max(maxValue, removed.val); + if (removed.left != null) { + queue.add(removed.left); + } + if (removed.right != null) { + queue.add(removed.right); + } + } + result.add(maxValue); } - } - list.add(maxVal); + return result; } - return list; - } } diff --git a/Medium/Find Leaves of Binary Tree.java b/Medium/Find Leaves of Binary Tree.java index 1bb713cd..c6449ce2 100644 --- a/Medium/Find Leaves of Binary Tree.java +++ b/Medium/Find Leaves of Binary Tree.java @@ -15,24 +15,43 @@ */ class Solution { public List> findLeaves(TreeNode root) { + Map parentMap = new HashMap<>(); + Queue leaves = new LinkedList<>(); + updateParentAndFindLeaves(root, null, parentMap, leaves); List> result = new ArrayList<>(); - helper(result, root); + while (!leaves.isEmpty()) { + int size = leaves.size(); + List temp = new ArrayList<>(); + while (size-- > 0) { + TreeNode removed = leaves.remove(); + temp.add(removed.val); + if (parentMap.get(removed) == null) { + continue; + } + if (parentMap.get(removed).left == removed) { + parentMap.get(removed).left = null; + } else { + parentMap.get(removed).right = null; + } + if (parentMap.get(removed).left == null && parentMap.get(removed).right == null) { + leaves.add(parentMap.get(removed)); + } + } + result.add(temp); + } return result; } - private int helper(List> result, TreeNode root) { - if (root == null) { - return -1; + private void updateParentAndFindLeaves(TreeNode node, TreeNode parent, Map parentMap, Queue leaves) { + if (node == null) { + return; } - int left = helper(result, root.left); - int right = helper(result, root.right); - int maxDepth = Math.max(left, right) + 1; - if (maxDepth == result.size()) { - result.add(new ArrayList<>()); + parentMap.put(node, parent); + if (node.left == null && node.right == null) { + leaves.add(node); + return; } - result.get(maxDepth).add(root.val); - // Cut the tree - root.left = root.right = null; - return maxDepth; + updateParentAndFindLeaves(node.left, node, parentMap, leaves); + updateParentAndFindLeaves(node.right, node, parentMap, leaves); } } diff --git a/Medium/Find Minimum Time to Reach Last Room I.java b/Medium/Find Minimum Time to Reach Last Room I.java new file mode 100644 index 00000000..0247baa4 --- /dev/null +++ b/Medium/Find Minimum Time to Reach Last Room I.java @@ -0,0 +1,36 @@ +class Solution { + + private static final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + + public int minTimeToReach(int[][] moveTime) { + int n = moveTime.length; + int m = moveTime[0].length; + boolean[][] visited = new boolean[n][m]; + Integer[][] minTime = new Integer[n][m]; + minTime[0][0] = 0; + PriorityQueue pq = new PriorityQueue<>((a, b) -> a[2] - b[2]); + pq.add(new int[]{0, 0, 0}); + while (!pq.isEmpty()) { + int[] removed = pq.remove(); + int x = removed[0]; + int y = removed[1]; + if (visited[x][y]) { + continue; + } + visited[x][y] = true; + for (int[] dir : DIRS) { + int newX = x + dir[0]; + int newY = y + dir[1]; + if (newX >= 0 && newY >= 0 && newX < n && newY < m) { + int distance = Math.max(minTime[x][y], moveTime[newX][newY]) + 1; + int currMinTime = minTime[newX][newY] == null ? Integer.MAX_VALUE : minTime[newX][newY]; + if (currMinTime > distance) { + minTime[newX][newY] = distance; + pq.add(new int[]{newX, newY, distance}); + } + } + } + } + return minTime[n - 1][m - 1]; + } +} diff --git a/Medium/Find Minimum in Rotated Sorted Array.java b/Medium/Find Minimum in Rotated Sorted Array.java index ef50804a..79ae6e51 100644 --- a/Medium/Find Minimum in Rotated Sorted Array.java +++ b/Medium/Find Minimum in Rotated Sorted Array.java @@ -1,21 +1,17 @@ class Solution { public int findMin(int[] nums) { int start = 0; - int end = nums.length-1; + int end = nums.length - 1; + int minValue = 5001; while (start <= end) { - int mid = (start + end)/2; - - if (((mid > 0 ? nums[mid] < nums[mid-1] : true) && (mid < nums.length-1 ? nums[mid] < nums[mid+1] : true))) { - return nums[mid]; - } - else if (nums[mid] < nums[end]) { - end = mid-1; - } - else { - start = mid+1; + int mid = (start + end) / 2; + minValue = Math.min(minValue, nums[mid]); + if (nums[end] > nums[mid]) { + end = mid - 1; + } else { + start = mid + 1; } } - - return -1; + return minValue; } } diff --git a/Medium/Find Missing Observations.java b/Medium/Find Missing Observations.java new file mode 100644 index 00000000..fe724572 --- /dev/null +++ b/Medium/Find Missing Observations.java @@ -0,0 +1,21 @@ +class Solution { + public int[] missingRolls(int[] rolls, int mean, int n) { + int m = rolls.length; + int sum = 0; + for (int roll : rolls) { + sum += roll; + } + int expectedSum = mean * (n + m); + int remaining = expectedSum - sum; + if (remaining > 6 * n || remaining < n) { + return new int[]{}; + } + int[] result = new int[n]; + Arrays.fill(result, remaining / n); + remaining = remaining % n; + for (int i = 0; i < remaining; i++) { + result[i]++; + } + return result; + } +} diff --git a/Medium/Find Nearest Right Node in Binary Tree.java b/Medium/Find Nearest Right Node in Binary Tree.java index 0388eddd..5fd92c97 100644 --- a/Medium/Find Nearest Right Node in Binary Tree.java +++ b/Medium/Find Nearest Right Node in Binary Tree.java @@ -14,22 +14,15 @@ * } */ class Solution { - public TreeNode findNeartestRightNode(TreeNode root, TreeNode u) { - if (root == null) { - return null; - } + public TreeNode findNearestRightNode(TreeNode root, TreeNode u) { Queue queue = new LinkedList<>(); queue.add(root); - boolean found = false; while (!queue.isEmpty()) { int size = queue.size(); - while (size-- > 0) { + while (size > 0) { TreeNode removed = queue.remove(); - if (found) { - return removed; - } - if (removed == u) { - found = true; + if (removed.equals(u)) { + return size == 1 ? null : queue.peek(); } if (removed.left != null) { queue.add(removed.left); @@ -37,9 +30,7 @@ public TreeNode findNeartestRightNode(TreeNode root, TreeNode u) { if (removed.right != null) { queue.add(removed.right); } - } - if (found) { - break; + size--; } } return null; diff --git a/Medium/Find Original Array From Doubled Array.java b/Medium/Find Original Array From Doubled Array.java new file mode 100644 index 00000000..55554c81 --- /dev/null +++ b/Medium/Find Original Array From Doubled Array.java @@ -0,0 +1,27 @@ +class Solution { + public int[] findOriginalArray(int[] changed) { + if (changed.length % 2 != 0) { + return new int[]{}; + } + Arrays.sort(changed); + Map map = new HashMap<>(); + for (int num : changed) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + int[] result = new int[changed.length / 2]; + int resultIdx = 0; + for (int num : changed) { + if (map.get(num) > 0) { + map.put(num, map.get(num) - 1); + int doubleValue = num * 2; + if (map.getOrDefault(doubleValue, 0) > 0) { + map.put(doubleValue, map.get(doubleValue) - 1); + result[resultIdx++] = num; + } else { + return new int[]{}; + } + } + } + return result; + } +} diff --git a/Medium/Find Peak Element.java b/Medium/Find Peak Element.java index b90994cc..5cc6feaa 100644 --- a/Medium/Find Peak Element.java +++ b/Medium/Find Peak Element.java @@ -1,25 +1,18 @@ class Solution { public int findPeakElement(int[] nums) { - int[] index = {-1}; - helper(nums, 0, nums.length - 1, index); - return index[0]; + return helper(nums, 0, nums.length - 1); } - private void helper(int[] nums, int start, int end, int[] index) { - if (start <= end && index[0] == -1) { - int mid = (start + end) / 2; - boolean found = ( - (mid + 1 < nums.length ? nums[mid] > nums[mid + 1] : true) && - (mid - 1 >= 0 ? nums[mid] > nums[mid - 1] : true) - ); - if (found) { - index[0] = mid; - return; - } - else { - helper(nums, start, mid - 1, index); - helper(nums, mid + 1, end, index); - } + private int helper(int[] nums, int startIdx, int endIdx) { + if (startIdx == endIdx) { + return startIdx; + } + int midIdx = (startIdx + endIdx) / 2; + int nextToMid = midIdx + 1; + if (nums[midIdx] > nums[nextToMid]) { + return helper(nums, startIdx, midIdx); + } else { + return helper(nums, nextToMid, endIdx); } } } diff --git a/Medium/Find Permutation.java b/Medium/Find Permutation.java index 2103c84f..0a081e7c 100644 --- a/Medium/Find Permutation.java +++ b/Medium/Find Permutation.java @@ -1,23 +1,27 @@ class Solution { public int[] findPermutation(String s) { - int[] ans = new int[s.length() + 1]; - Stack stack = new Stack<>(); - int idx = 0; - for (int i = 1; i <= s.length(); i++) { - if (s.charAt(i - 1) == 'I') { - stack.push(i); - while (!stack.isEmpty()) { - ans[idx++] = stack.pop(); - } - } - else { - stack.push(i); + int n = s.length(); + int[] result = new int[n + 1]; + for (int i = 0; i < result.length; i++) { + result[i] = i + 1; + } + int idx = 1; + while (idx <= n) { + int k = idx; + while (idx <= n && s.charAt(idx - 1) == 'D') { + idx++; } + reverse(result, k - 1, idx); + idx++; } - stack.push(s.length() + 1); - while (!stack.isEmpty()) { - ans[idx++] = stack.pop(); + return result; + } + + private void reverse(int[] result, int start, int end) { + for (int i = 0; i < (end - start) / 2; i++) { + int temp = result[i + start]; + result[i + start] = result[end - i - 1]; + result[end - i - 1] = temp; } - return ans; - } + } } diff --git a/Medium/Find Players With Zero or One Losses.java b/Medium/Find Players With Zero or One Losses.java new file mode 100644 index 00000000..1692f1e5 --- /dev/null +++ b/Medium/Find Players With Zero or One Losses.java @@ -0,0 +1,22 @@ +class Solution { + public List> findWinners(int[][] matches) { + Map playerToLossCount = new HashMap<>(); + for (int[] match : matches) { + int winner = match[0]; + int loser = match[1]; + playerToLossCount.putIfAbsent(winner, 0); + playerToLossCount.put(loser, playerToLossCount.getOrDefault(loser, 0) + 1); + } + List> result = new ArrayList<>( + Arrays.asList(new ArrayList<>(), new ArrayList<>()) + ); + for (Map.Entry entry : playerToLossCount.entrySet()) { + if (entry.getValue() <= 1) { + result.get(entry.getValue()).add(entry.getKey()); + } + } + Collections.sort(result.get(0)); + Collections.sort(result.get(1)); + return result; + } +} diff --git a/Medium/Find Polygon With the Largest Perimeter.java b/Medium/Find Polygon With the Largest Perimeter.java new file mode 100644 index 00000000..8b368cb2 --- /dev/null +++ b/Medium/Find Polygon With the Largest Perimeter.java @@ -0,0 +1,15 @@ +class Solution { + public long largestPerimeter(int[] nums) { + Arrays.sort(nums); + int n = nums.length; + long prefixSum = 0; + long result = -1; + for (int i = 0; i < n; i++) { + if (i >= 2 && nums[i] < prefixSum) { + result = nums[i] + prefixSum; + } + prefixSum += nums[i]; + } + return result; + } +} diff --git a/Medium/Find The First Player to win K Games in a Row.java b/Medium/Find The First Player to win K Games in a Row.java new file mode 100644 index 00000000..fe26c684 --- /dev/null +++ b/Medium/Find The First Player to win K Games in a Row.java @@ -0,0 +1,24 @@ +class Solution { + public int findWinningPlayer(int[] skills, int k) { + Map indexMap = new HashMap<>(); + for (int i = 0; i < skills.length; i++) { + indexMap.put(skills[i], i); + } + Map winCountMap = new HashMap<>(); + Deque deque = new ArrayDeque<>(); + for (int num : skills) { + deque.addFirst(num); + } + while (deque.size() > 1) { + int first = deque.pollLast(); + int second = deque.pollLast(); + int winner = Math.max(first, second); + winCountMap.put(winner, winCountMap.getOrDefault(winner, 0) + 1); + deque.addLast(winner); + if (winCountMap.get(winner) == k) { + return indexMap.get(winner); + } + } + return indexMap.get(deque.poll()); + } +} diff --git a/Medium/Find The Original Array of Prefix Xor.java b/Medium/Find The Original Array of Prefix Xor.java new file mode 100644 index 00000000..46732ae1 --- /dev/null +++ b/Medium/Find The Original Array of Prefix Xor.java @@ -0,0 +1,11 @@ +class Solution { + public int[] findArray(int[] pref) { + int n = pref.length; + int[] result = new int[n]; + result[0] = pref[0]; + for (int i = 1; i < n; i++) { + result[i] = pref[i - 1] ^ pref[i]; + } + return result; + } +} diff --git a/Medium/Find Triangular Sum of an Array.java b/Medium/Find Triangular Sum of an Array.java new file mode 100644 index 00000000..0da1ef52 --- /dev/null +++ b/Medium/Find Triangular Sum of an Array.java @@ -0,0 +1,12 @@ +class Solution { + public int triangularSum(int[] nums) { + int n = nums.length; + while (n > 1) { + for (int i = 0; i + 1 < n; i++) { + nums[i] = (nums[i] + nums[i + 1]) % 10; + } + n--; + } + return nums[0]; + } +} diff --git a/Medium/Find Unique Binary String.java b/Medium/Find Unique Binary String.java new file mode 100644 index 00000000..80cdfa9e --- /dev/null +++ b/Medium/Find Unique Binary String.java @@ -0,0 +1,25 @@ +class Solution { + + private static final char[] BINARY_CHARS = {'1', '0'}; + + public String findDifferentBinaryString(String[] nums) { + int n = nums.length; + Set binaryStrings = new HashSet<>(); + backtrack(new StringBuilder(), n, binaryStrings); + Set binaryStringsPresent = Arrays.stream(nums).collect(Collectors.toSet()); + binaryStrings.removeAll(binaryStringsPresent); + return binaryStrings.isEmpty() ? "" : binaryStrings.iterator().next(); + } + + private void backtrack(StringBuilder sb, int n, Set binaryStrings) { + if (sb.length() == n) { + binaryStrings.add(sb.toString()); + return; + } + for (char c : BINARY_CHARS) { + sb.append(c); + backtrack(sb, n, binaryStrings); + sb.deleteCharAt(sb.length() - 1); + } + } +} diff --git a/Medium/Find a Corresponding Node of a Binary Tree in a Clone of That Tree.java b/Medium/Find a Corresponding Node of a Binary Tree in a Clone of That Tree.java index 6be836db..0373fe3f 100644 --- a/Medium/Find a Corresponding Node of a Binary Tree in a Clone of That Tree.java +++ b/Medium/Find a Corresponding Node of a Binary Tree in a Clone of That Tree.java @@ -10,13 +10,25 @@ class Solution { public final TreeNode getTargetCopy(final TreeNode original, final TreeNode cloned, final TreeNode target) { - if (original == null || original == target) { - return cloned; + Deque stackOriginal = new ArrayDeque<>(); + Deque stackCloned = new ArrayDeque<>(); + TreeNode nodeOriginal = original; + TreeNode nodeCloned = cloned; + while (!stackOriginal.isEmpty() || nodeOriginal != null) { + while (nodeOriginal != null) { + stackOriginal.add(nodeOriginal); + stackCloned.add(nodeCloned); + nodeOriginal = nodeOriginal.left; + nodeCloned = nodeCloned.left; + } + nodeOriginal = stackOriginal.removeLast(); + nodeCloned = stackCloned.removeLast(); + if (nodeOriginal == target) { + return nodeCloned; + } + nodeOriginal = nodeOriginal.right; + nodeCloned = nodeCloned.right; } - TreeNode leftResult = getTargetCopy(original.left, cloned.left, target); - if (leftResult != null) { - return leftResult; - } - return getTargetCopy(original.right, cloned.right, target); + return null; } } diff --git a/Medium/Find and Replace Pattern.java b/Medium/Find and Replace Pattern.java index 8a54adbe..c3cd1593 100644 --- a/Medium/Find and Replace Pattern.java +++ b/Medium/Find and Replace Pattern.java @@ -1,21 +1,15 @@ class Solution { public List findAndReplacePattern(String[] words, String pattern) { - String patternCode = getCode(pattern); - List list = new ArrayList<>(); - for (String word : words) { - String wordCode = getCode(word); - if (wordCode.equals(patternCode)) { - list.add(word); - } - } - return list; + String patternString = getPattern(pattern); + return Arrays.stream(words).filter(e -> getPattern(e).equals(patternString)) + .collect(Collectors.toList()); } - private String getCode(String word) { - Map map = new HashMap<>(); + private String getPattern(String s) { StringBuilder sb = new StringBuilder(); - int count = 0; - for (char c : word.toCharArray()) { + Map map = new HashMap<>(); + int count = 1; + for (char c : s.toCharArray()) { if (!map.containsKey(c)) { map.put(c, count++); } diff --git a/Medium/Find if Array Can Be Sorted.java b/Medium/Find if Array Can Be Sorted.java new file mode 100644 index 00000000..8b08e457 --- /dev/null +++ b/Medium/Find if Array Can Be Sorted.java @@ -0,0 +1,18 @@ +class Solution { + public boolean canSortArray(int[] nums) { + int lastGroupHighest = 0; + int highest = nums[0]; + boolean bitChange = false; + for (int i = 1; i < nums.length; i++) { + bitChange = Integer.bitCount(highest) != Integer.bitCount(nums[i]); + if (bitChange) { + lastGroupHighest = highest; + } + highest = Math.max(nums[i], highest); + if (nums[i] < lastGroupHighest) { + return false; + } + } + return true; + } +} diff --git a/Medium/Find the City With the Smallest Number of Neighbors at a Threshold Distance.java b/Medium/Find the City With the Smallest Number of Neighbors at a Threshold Distance.java index 08292d1d..92c4b6a4 100644 --- a/Medium/Find the City With the Smallest Number of Neighbors at a Threshold Distance.java +++ b/Medium/Find the City With the Smallest Number of Neighbors at a Threshold Distance.java @@ -1,37 +1,45 @@ class Solution { public int findTheCity(int n, int[][] edges, int distanceThreshold) { - Map> map = new HashMap<>(); + Map> graph = new HashMap<>(); for (int[] edge : edges) { - map.computeIfAbsent(edge[0], k -> new HashMap<>()).put(edge[1], edge[2]); - map.computeIfAbsent(edge[1], k -> new HashMap<>()).put(edge[0], edge[2]); + graph.computeIfAbsent(edge[0], k -> new ArrayList<>()) + .add(new int[]{edge[1], edge[2]}); + graph.computeIfAbsent(edge[1], k -> new ArrayList<>()) + .add(new int[]{edge[0], edge[2]}); } - int min = n + 1; - int res = -1; + int minNeighborCount = n + 1; + int nodeWithMinNeighbor = -1; for (int i = 0; i < n; i++) { - Queue queue = new PriorityQueue<>((a, b) -> (b[1] - a[1])); - queue.add(new int[]{i, distanceThreshold}); - boolean[] visited = new boolean[n]; - int count = 0; - while (!queue.isEmpty()) { - int[] city = queue.poll(); - if (visited[city[0]]) { - continue; - } - visited[city[0]] = true; - count++; - Map temp = map.getOrDefault(city[0], new HashMap<>()); - for (Integer neighbour : temp.keySet()) { - if (!visited[neighbour] && city[1] >= temp.get(neighbour)) { - queue.add(new int[]{neighbour, city[1] - temp.get(neighbour)}); - } - } + int numOfNeighbors = findNumberOfNeighborsWithinThresholdDistance(i, distanceThreshold, graph); + minNeighborCount = Math.min(numOfNeighbors, minNeighborCount); + nodeWithMinNeighbor = minNeighborCount == numOfNeighbors ? i : nodeWithMinNeighbor; + } + return nodeWithMinNeighbor; + } + + private int findNumberOfNeighborsWithinThresholdDistance(int node, int distanceThreshold, Map> graph) { + Queue queue = new PriorityQueue<>((a, b) -> (b[1] - a[1])); + Set visited = new HashSet<>(); + queue.add(new int[]{node, distanceThreshold}); + int numOfNeighbors = 0; + while (!queue.isEmpty()) { + int[] removed = queue.remove(); + int currNode = removed[0]; + int currDistanceThreshold = removed[1]; + if (visited.contains(currNode)) { + continue; } - if (count - 1 <= min) { - min = count - 1; - res = i; + visited.add(currNode); + numOfNeighbors++; + for (int[] neighbor : graph.getOrDefault(currNode, new ArrayList<>())) { + int neighborNode = neighbor[0]; + int neighborDistance = neighbor[1]; + if (!visited.contains(neighborNode) && + currDistanceThreshold >= neighborDistance) { + queue.add(new int[]{neighborNode, currDistanceThreshold - neighborDistance}); + } } } - return res; + return numOfNeighbors; } } - diff --git a/Medium/Find the Duplicate Number.java b/Medium/Find the Duplicate Number.java new file mode 100644 index 00000000..bfd8908b --- /dev/null +++ b/Medium/Find the Duplicate Number.java @@ -0,0 +1,20 @@ +class Solution { + public int findDuplicate(int[] nums) { + int slow = nums[0]; + int fast = nums[0]; + while (true) { + slow = nums[slow]; + fast = nums[nums[fast]]; + if (slow == fast) { + break; + } + } + int idxOne = nums[0]; + int idxTwo = slow; + while (idxOne != idxTwo) { + idxOne = nums[idxOne]; + idxTwo = nums[idxTwo]; + } + return idxOne; + } +} diff --git a/Medium/Find the Index of the First Occurrence in a String.java b/Medium/Find the Index of the First Occurrence in a String.java new file mode 100644 index 00000000..4156d0ba --- /dev/null +++ b/Medium/Find the Index of the First Occurrence in a String.java @@ -0,0 +1,10 @@ +class Solution { + public int strStr(String haystack, String needle) { + for (int i = 0; i <= haystack.length() - needle.length(); i++) { + if (haystack.substring(i, i + needle.length()).equals(needle)) { + return i; + } + } + return -1; + } +} diff --git a/Medium/Find the Kth Largest Integer in the Array.java b/Medium/Find the Kth Largest Integer in the Array.java new file mode 100644 index 00000000..cc335042 --- /dev/null +++ b/Medium/Find the Kth Largest Integer in the Array.java @@ -0,0 +1,7 @@ +class Solution { + public String kthLargestNumber(String[] nums, int k) { + Arrays.sort(nums, (o1, o2) -> + o1.length() == o2.length() ? o1.compareTo(o2) : o1.length() - o2.length()); + return nums[nums.length - k]; + } +} diff --git a/Medium/Find the Length of the Longest Common Prefix.java b/Medium/Find the Length of the Longest Common Prefix.java new file mode 100644 index 00000000..a626cd3a --- /dev/null +++ b/Medium/Find the Length of the Longest Common Prefix.java @@ -0,0 +1,52 @@ +class Solution { + public int longestCommonPrefix(int[] arr1, int[] arr2) { + TrieNodeManager nodeManager = new TrieNodeManager(); + for (int num : arr1) { + nodeManager.index(String.valueOf(num)); + } + int maxLength = 0; + for (int num : arr2) { + int length = nodeManager.find(String.valueOf(num)); + maxLength = Math.max(maxLength, length); + } + return maxLength; + } + + private static class TrieNodeManager { + + private Node root; + + public TrieNodeManager() { + this.root = new Node(); + } + + public void index(String s) { + Node curr = root; + for (char c : s.toCharArray()) { + if (!curr.children.containsKey(c)) { + curr.children.put(c, new Node()); + } + curr = curr.children.get(c); + } + } + + public int find(String s) { + Node curr = root; + for (int i = 0; i < s.length(); i++) { + if (!curr.children.containsKey(s.charAt(i))) { + return i; + } + curr = curr.children.get(s.charAt(i)); + } + return s.length(); + } + + class Node { + Map children; + + public Node() { + this.children = new HashMap<>(); + } + } + } +} diff --git a/Medium/Find the Lexicographically Largest String From the Box I.java b/Medium/Find the Lexicographically Largest String From the Box I.java new file mode 100644 index 00000000..1133cb93 --- /dev/null +++ b/Medium/Find the Lexicographically Largest String From the Box I.java @@ -0,0 +1,16 @@ +class Solution { + public String answerString(String word, int numFriends) { + if (numFriends == 1) { + return word; + } + int n = word.length(); + String result = ""; + for (int i = 0; i < n; i++) { + String curr = word.substring(i, Math.min(i + n - numFriends + 1, n)); + if (result.compareTo(curr) <= 0) { + result = curr; + } + } + return result; + } +} diff --git a/Medium/Find the Longest Semi-Repetitive Substring.java b/Medium/Find the Longest Semi-Repetitive Substring.java new file mode 100644 index 00000000..f6743a56 --- /dev/null +++ b/Medium/Find the Longest Semi-Repetitive Substring.java @@ -0,0 +1,22 @@ +class Solution { + public int longestSemiRepetitiveSubstring(String s) { + int start = 0; + int end = 0; + int maxLength = 1; + int consecutiveCount = 0; + while (end < s.length() - 1) { + if (s.charAt(end) == s.charAt(end + 1)) { + consecutiveCount++; + } + end++; + while (start < end && consecutiveCount > 1) { + if (s.charAt(start) == s.charAt(start + 1)) { + consecutiveCount--; + } + start++; + } + maxLength = Math.max(maxLength, end - start + 1); + } + return maxLength; + } +} diff --git a/Medium/Find the Longest Substring Containing Vowels in Even Counts.java b/Medium/Find the Longest Substring Containing Vowels in Even Counts.java new file mode 100644 index 00000000..66e33ef9 --- /dev/null +++ b/Medium/Find the Longest Substring Containing Vowels in Even Counts.java @@ -0,0 +1,22 @@ +class Solution { + public int findTheLongestSubstring(String s) { + int prefixXor = 0; + char[] frequency = new char[26]; + frequency['a' - 'a'] = 1; + frequency['e' - 'a'] = 2; + frequency['i' - 'a'] = 4; + frequency['o' - 'a'] = 8; + frequency['u' - 'a'] = 16; + int[] indexMap = new int[32]; + Arrays.fill(indexMap, -1); + int result = 0; + for (int i = 0; i < s.length(); i++) { + prefixXor ^= frequency[s.charAt(i) - 'a']; + if (indexMap[prefixXor] == -1 && prefixXor != 0) { + indexMap[prefixXor] = i; + } + result = Math.max(result, i - indexMap[prefixXor]); + } + return result; + } +} diff --git a/Medium/Find the Maximum Divisibility Score.java b/Medium/Find the Maximum Divisibility Score.java new file mode 100644 index 00000000..2e33ee9a --- /dev/null +++ b/Medium/Find the Maximum Divisibility Score.java @@ -0,0 +1,19 @@ +class Solution { + public int maxDivScore(int[] nums, int[] divisors) { + int maxScore = -1; + int maxScoreCandidate = -1; + for (int divisor : divisors) { + int currScore = 0; + for (int num : nums) { + currScore += num % divisor == 0 ? 1 : 0; + } + if (currScore > maxScore) { + maxScore = currScore; + maxScoreCandidate = divisor; + } else if (currScore == maxScore) { + maxScoreCandidate = Math.min(maxScoreCandidate, divisor); + } + } + return maxScoreCandidate; + } +} diff --git a/Medium/Find the Maximum Number of Elements in Subset.java b/Medium/Find the Maximum Number of Elements in Subset.java new file mode 100644 index 00000000..4c419cbc --- /dev/null +++ b/Medium/Find the Maximum Number of Elements in Subset.java @@ -0,0 +1,19 @@ +class Solution { + public int maximumLength(int[] nums) { + Map map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + int result = map.containsKey(1) ? (map.get(1) % 2 == 0 ? map.get(1) - 1 : map.get(1)) : 1; + for (int num : nums) { + int count = 0; + while (map.containsKey(num) && map.get(num) >= 2 && num != 1) { + count += 2; + num *= num; + } + count += map.containsKey(num) ? 1 : -1; + result = Math.max(result, count); + } + return result; + } +} diff --git a/Medium/Find the Minimum Area to Cover All Ones I.java b/Medium/Find the Minimum Area to Cover All Ones I.java new file mode 100644 index 00000000..538bf894 --- /dev/null +++ b/Medium/Find the Minimum Area to Cover All Ones I.java @@ -0,0 +1,24 @@ +class Solution { + public int minimumArea(int[][] grid) { + int minRow = Integer.MAX_VALUE; + int minCol = Integer.MAX_VALUE; + int maxRow = Integer.MIN_VALUE; + int maxCol = Integer.MIN_VALUE; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 1) { + minRow = Math.min(minRow, i); + minCol = Math.min(minCol, j); + maxRow = Math.max(maxRow, i); + maxCol = Math.max(maxCol, j); + } + } + } + if (minRow == Integer.MAX_VALUE) { + return 0; + } + int length = maxRow - minRow + 1; + int breadth = maxCol - minCol + 1; + return length * breadth; + } +} diff --git a/Medium/Find the Minimum and Maximum Number of Nodes Between Critical Points.java b/Medium/Find the Minimum and Maximum Number of Nodes Between Critical Points.java new file mode 100644 index 00000000..dfab1434 --- /dev/null +++ b/Medium/Find the Minimum and Maximum Number of Nodes Between Critical Points.java @@ -0,0 +1,31 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public int[] nodesBetweenCriticalPoints(ListNode head) { + int firstIdx = Integer.MAX_VALUE; + int lastIdx = 0; + int minDistance = Integer.MAX_VALUE; + int prevVal = head.val; + for (int i = 0; head.next != null; i++) { + if ((prevVal < head.val && head.next.val < head.val) || + (prevVal > head.val && head.next.val > head.val)) { + if (lastIdx != 0) { + minDistance = Math.min(minDistance, i - lastIdx); + } + firstIdx = Math.min(firstIdx, i); + lastIdx = i; + } + prevVal = head.val; + head = head.next; + } + return minDistance == Integer.MAX_VALUE ? new int[]{-1, -1} : new int[]{minDistance, lastIdx - firstIdx}; + } +} diff --git a/Medium/Find the N-th Value After K Seconds.java b/Medium/Find the N-th Value After K Seconds.java new file mode 100644 index 00000000..e457d0eb --- /dev/null +++ b/Medium/Find the N-th Value After K Seconds.java @@ -0,0 +1,15 @@ +class Solution { + + private final int MOD = 1000_000_007; + + public int valueAfterKSeconds(int n, int k) { + int[] arr = new int[n]; + Arrays.fill(arr, 1); + while (k-- > 0) { + for (int i = 1; i < n; i++) { + arr[i] = (arr[i] + arr[i - 1]) % MOD; + } + } + return arr[n - 1]; + } +} diff --git a/Medium/Find the Number of Distinct Colors Among the Balls.java b/Medium/Find the Number of Distinct Colors Among the Balls.java new file mode 100644 index 00000000..428e5406 --- /dev/null +++ b/Medium/Find the Number of Distinct Colors Among the Balls.java @@ -0,0 +1,23 @@ +class Solution { + public int[] queryResults(int limit, int[][] queries) { + Map ballToColor = new HashMap<>(); + Map colorToBallCount = new HashMap<>(); + int n = queries.length; + int[] result = new int[n]; + for (int i = 0; i < queries.length; i++) { + int ball = queries[i][0]; + int color = queries[i][1]; + if (ballToColor.containsKey(ball)) { + int prevColor = ballToColor.get(ball); + colorToBallCount.put(prevColor, colorToBallCount.get(prevColor) - 1); + if (colorToBallCount.get(prevColor) == 0) { + colorToBallCount.remove(prevColor); + } + } + ballToColor.put(ball, color); + colorToBallCount.put(color, colorToBallCount.getOrDefault(color, 0) + 1); + result[i] = colorToBallCount.size(); + } + return result; + } +} diff --git a/Medium/Find the Prefix Common Array of Two Arrays.java b/Medium/Find the Prefix Common Array of Two Arrays.java new file mode 100644 index 00000000..e6312a17 --- /dev/null +++ b/Medium/Find the Prefix Common Array of Two Arrays.java @@ -0,0 +1,20 @@ +class Solution { + public int[] findThePrefixCommonArray(int[] A, int[] B) { + int count = 0; + int n = A.length; + int[] result = new int[n]; + int[] frequency = new int[n + 1]; + for (int i = 0; i < n; i++) { + frequency[A[i]]++; + if (frequency[A[i]] == 2) { + count++; + } + frequency[B[i]]++; + if (frequency[B[i]] == 2) { + count++; + } + result[i] = count; + } + return result; + } +} diff --git a/Medium/Find the Score of All Prefixes of an Array.java b/Medium/Find the Score of All Prefixes of an Array.java new file mode 100644 index 00000000..ff88ca98 --- /dev/null +++ b/Medium/Find the Score of All Prefixes of an Array.java @@ -0,0 +1,17 @@ +class Solution { + public long[] findPrefixScore(int[] nums) { + int[] conver = new int[nums.length]; + int max = nums[0]; + for (int i = 0; i < nums.length; i++) { + max = Math.max(max, nums[i]); + conver[i] = nums[i] + max; + } + long[] result = new long[nums.length]; + long score = 0; + for (int i = 0; i < nums.length; i++) { + score += conver[i]; + result[i] = score; + } + return result; + } +} diff --git a/Medium/Find the Student that Will Replace the Chalk.java b/Medium/Find the Student that Will Replace the Chalk.java new file mode 100644 index 00000000..bdf79d9a --- /dev/null +++ b/Medium/Find the Student that Will Replace the Chalk.java @@ -0,0 +1,23 @@ +class Solution { + public int chalkReplacer(int[] chalk, int k) { + int n = chalk.length; + long[] prefixSum = new long[n]; + prefixSum[0] = chalk[0]; + for (int i = 1; i < n; i++) { + prefixSum[i] = chalk[i] + prefixSum[i - 1]; + } + long total = prefixSum[n - 1]; + long remaining = k % total; + int left = 0; + int right = n - 1; + while (left < right) { + int mid = (left + right) / 2; + if (prefixSum[mid] <= remaining) { + left = mid + 1; + } else { + right = mid; + } + } + return right; + } +} diff --git a/Medium/Find the Substring With Maximum Cost.java b/Medium/Find the Substring With Maximum Cost.java new file mode 100644 index 00000000..24e00548 --- /dev/null +++ b/Medium/Find the Substring With Maximum Cost.java @@ -0,0 +1,16 @@ +class Solution { + public int maximumCostSubstring(String s, String chars, int[] vals) { + Map valueMap = new HashMap<>(); + for (int i = 0; i < chars.length(); i++) { + valueMap.put(chars.charAt(i), vals[i]); + } + int maxCost = 0; + int currCost = 0; + for (char c : s.toCharArray()) { + int currCharCost = valueMap.containsKey(c) ? valueMap.get(c) : (c - 'a' + 1); + currCost = Math.max(currCharCost, currCost + currCharCost); + maxCost = Math.max(currCost, maxCost); + } + return maxCost; + } +} diff --git a/Medium/Find the Town Judge.java b/Medium/Find the Town Judge.java deleted file mode 100644 index e8597e29..00000000 --- a/Medium/Find the Town Judge.java +++ /dev/null @@ -1,15 +0,0 @@ -class Solution { - public int findJudge(int N, int[][] trust) { - int[] trustScore = new int[N + 1]; - for (int[] trst : trust) { - trustScore[trst[0]]--; - trustScore[trst[1]]++; - } - for (int i = 1; i <= N; i++) { - if (trustScore[i] == (N - 1)) { - return i; - } - } - return -1; - } -} diff --git a/Medium/Find the Winner of an Array Game.java b/Medium/Find the Winner of an Array Game.java new file mode 100644 index 00000000..98932a1e --- /dev/null +++ b/Medium/Find the Winner of an Array Game.java @@ -0,0 +1,16 @@ +class Solution { + public int getWinner(int[] arr, int k) { + int curr = arr[0]; + int streak = 0; + for (int i = 1; i < arr.length; i++) { + if (curr < arr[i]) { + curr = arr[i]; + streak = 0; + } + if (++streak == k) { + break; + } + } + return curr; + } +} diff --git a/Medium/Find the Winner of the Circular Game.java b/Medium/Find the Winner of the Circular Game.java new file mode 100644 index 00000000..816b3aa4 --- /dev/null +++ b/Medium/Find the Winner of the Circular Game.java @@ -0,0 +1,15 @@ +class Solution { + public int findTheWinner(int n, int k) { + Queue circle = new LinkedList<>(); + for (int i = 1; i <= n; i++) { + circle.add(i); + } + while (circle.size() > 1) { + for (int i = 0; i < k - 1; i++) { + circle.add(circle.remove()); + } + circle.remove(); + } + return circle.peek(); + } +} diff --git a/Medium/Find the duplicate number.java b/Medium/Find the duplicate number.java deleted file mode 100644 index d05d0a60..00000000 --- a/Medium/Find the duplicate number.java +++ /dev/null @@ -1,20 +0,0 @@ -class Solution { - public int findDuplicate(int[] nums) { - int tortoise = nums[0]; - int hare = nums[0]; - while(true) { - tortoise = nums[tortoise]; - hare = nums[nums[hare]]; - if (tortoise == hare) { - break; - } - } - int p1 = nums[0]; - int p2 = tortoise; - while (p1 != p2) { - p1 = nums[p1]; - p2 = nums[p2]; - } - return p1; - } -} diff --git a/Medium/Finding the Users Active Minutes.java b/Medium/Finding the Users Active Minutes.java new file mode 100644 index 00000000..45c9c86c --- /dev/null +++ b/Medium/Finding the Users Active Minutes.java @@ -0,0 +1,16 @@ +class Solution { + public int[] findingUsersActiveMinutes(int[][] logs, int k) { + Map> map = new HashMap<>(); + for (int[] log : logs) { + int id = log[0]; + int minute = log[1]; + map.computeIfAbsent(id, j -> new HashSet<>()).add(minute); + } + int[] result = new int[k]; + for (Integer key : map.keySet()) { + int uam = map.get(key).size(); + result[uam - 1]++; + } + return result; + } +} diff --git a/Medium/First Unique Number.java b/Medium/First Unique Number.java index 9a0dd44e..6affb411 100644 --- a/Medium/First Unique Number.java +++ b/Medium/First Unique Number.java @@ -1,57 +1,27 @@ class FirstUnique { - Node head; - Node tail; - Map map; - int MX_VAL = Integer.MAX_VALUE; - int MN_VAL = Integer.MIN_VALUE; - public FirstUnique(int[] nums) { - map = new HashMap<>(); - head = new Node(MN_VAL); - tail = new Node(MX_VAL); - head.next = tail; - tail.prev = head; - for (int num : nums) { - add(num); - } - } - public int showFirstUnique() { - return head.next.val == MX_VAL ? -1 : head.next.val; - } + private Map map; + private Queue queue; - public void add(int value) { - if (map.containsKey(value)) { - if (map.get(value) != null) { - remove(map.get(value)); - map.put(value, null); - } + public FirstUnique(int[] nums) { + map = new HashMap<>(); + queue = new LinkedList<>(); + for (int num : nums) { + add(num); + } } - else { - Node newNode = new Node(value); - map.put(value, newNode); - newNode.prev = tail.prev; - tail.prev.next = newNode; - newNode.next = tail; - tail.prev = newNode; + + public int showFirstUnique() { + while (!queue.isEmpty() && map.get(queue.peek()) > 1) { + queue.remove(); + } + return queue.isEmpty() ? -1 : queue.peek(); + } + + public void add(int value) { + queue.add(value); + map.put(value, map.getOrDefault(value, 0) + 1); } - } - - private void remove(Node node) { - Node prev = node.prev; - Node next = node.next; - prev.next = next; - next.prev = prev; - } -} - -class Node { - int val; - Node next; - Node prev; - - public Node(int val) { - this.val = val; - } } /** diff --git a/Medium/Flatten 2D Vector.java b/Medium/Flatten 2D Vector.java index c9c0ce8c..83fd6e2e 100644 --- a/Medium/Flatten 2D Vector.java +++ b/Medium/Flatten 2D Vector.java @@ -1,33 +1,31 @@ +import java.util.PrimitiveIterator.OfInt; + class Vector2D { - int vectorIdx; - int currIdx; - int[][] v; - public Vector2D(int[][] v) { - vectorIdx = 0; - currIdx = 0; - this.v = v; + + private Iterator iterators; + private Iterator currIterator; + + public Vector2D(int[][] vec) { + this.iterators = Arrays.stream(vec).map(v -> Arrays.stream(v).iterator()).iterator(); + this.currIterator = Collections.emptyIterator();; } public int next() { hasNext(); - return v[vectorIdx][currIdx++]; + return (int) this.currIterator.next(); } public boolean hasNext() { - while (vectorIdx < v.length) { - if (currIdx < v[vectorIdx].length) { - return true; - } - vectorIdx++; - currIdx = 0; + while (!this.currIterator.hasNext() && this.iterators.hasNext()) { + this.currIterator = this.iterators.next(); } - return false; + return this.currIterator.hasNext(); } } /** * Your Vector2D object will be instantiated and called as such: - * Vector2D obj = new Vector2D(v); + * Vector2D obj = new Vector2D(vec); * int param_1 = obj.next(); * boolean param_2 = obj.hasNext(); */ diff --git a/Medium/Flatten Nested List Iterator.java b/Medium/Flatten Nested List Iterator.java index 0a54bc02..087bc1ef 100644 --- a/Medium/Flatten Nested List Iterator.java +++ b/Medium/Flatten Nested List Iterator.java @@ -11,53 +11,40 @@ * public Integer getInteger(); * * // @return the nested list that this NestedInteger holds, if it holds a nested list - * // Return null if this NestedInteger holds a single integer + * // Return empty list if this NestedInteger holds a single integer * public List getList(); * } */ public class NestedIterator implements Iterator { - List nestedList; - Queue queue; - int idx; - public NestedIterator(List nestedList) { - this.nestedList = nestedList; - queue = new LinkedList<>(); - idx = 0; - addToQueue(); - } - @Override - public Integer next() { - int val = queue.remove(); - if (queue.isEmpty()) { - if (idx != nestedList.size()) { - addToQueue(); - } - } - return val; - } - - private void addToQueue() { - while (idx < nestedList.size() && queue.isEmpty()) { - addToQueueHelper(nestedList.get(idx++)); - } - } - - private void addToQueueHelper(NestedInteger ns) { - if (ns.isInteger()) { - queue.add(ns.getInteger()); + private Stack stack; + + public NestedIterator(List nestedList) { + this.stack = new Stack<>(); + for (int i = nestedList.size() - 1; i >= 0; i--) { + this.stack.push(nestedList.get(i)); + } } - else { - for (NestedInteger ni : ns.getList()) { - addToQueueHelper(ni); - } + + @Override + public Integer next() { + return stack.pop().getInteger(); } - } - @Override - public boolean hasNext() { - return !(queue.isEmpty() && idx == nestedList.size()); - } + @Override + public boolean hasNext() { + while (!stack.isEmpty() && !stack.peek().isInteger()) { + NestedInteger popped = stack.pop(); + if (popped == null) { + continue; + } + List list = popped.getList(); + for (int i = list.size() - 1; i >= 0; i--) { + stack.push(list.get(i)); + } + } + return !stack.isEmpty(); + } } /** diff --git a/Medium/Flatten a Multilevel Doubly Linked List.java b/Medium/Flatten a Multilevel Doubly Linked List.java index 47dfdbb2..3708998f 100644 --- a/Medium/Flatten a Multilevel Doubly Linked List.java +++ b/Medium/Flatten a Multilevel Doubly Linked List.java @@ -11,27 +11,24 @@ class Node { class Solution { public Node flatten(Node head) { if (head == null) { - return null; + return head; } Stack stack = new Stack<>(); stack.push(head); - Node dummy = new Node(0, null, head, null); - Node prev = dummy; - Node curr = dummy; while (!stack.isEmpty()) { - curr = stack.pop(); - prev.next = curr; - curr.prev = prev; - if (curr.next != null) { - stack.push(curr.next); + Node removed = stack.pop(); + if (removed.next != null) { + stack.push(removed.next); } - if (curr.child != null) { - stack.push(curr.child); - curr.child = null; + if (removed.child != null) { + stack.push(removed.child); + } + removed.child = null; + if (!stack.isEmpty()) { + removed.next = stack.peek(); + stack.peek().prev = removed; } - prev = curr; } - dummy.next.prev = null; - return dummy.next; - } + return head; + } } diff --git a/Medium/Flip Equivalent Binary Trees.java b/Medium/Flip Equivalent Binary Trees.java index 7829ff4d..8590505e 100644 --- a/Medium/Flip Equivalent Binary Trees.java +++ b/Medium/Flip Equivalent Binary Trees.java @@ -1,31 +1,31 @@ -i/** +/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public boolean flipEquiv(TreeNode root1, TreeNode root2) { - if (root1 == null && root2 == null) { - return true; + public boolean flipEquiv(TreeNode root1, TreeNode root2) { + if (root1 == null && root2 == null) { + return true; + } + if (root1 == null || root2 == null) { + return false; + } + if (root1.val != root2.val) { + return false; + } + boolean noSwap = flipEquiv(root1.left, root2.left) && flipEquiv(root1.right, root2.right); + boolean swap = flipEquiv(root1.left, root2.right) && flipEquiv(root1.right, root2.left); + return noSwap || swap; } - if (root1 == null || root2 == null) { - return false; - } - if (root1.val != root2.val) { - return false; - } - return ( - ( - flipEquiv(root1.left, root2.left) && flipEquiv(root1.right, root2.right) - ) || - ( - flipEquiv(root1.left, root2.right) && - flipEquiv(root1.right, root2.left) - ) - ); - } } diff --git a/Medium/Fraction Addition and Subtraction.java b/Medium/Fraction Addition and Subtraction.java new file mode 100644 index 00000000..3d26da63 --- /dev/null +++ b/Medium/Fraction Addition and Subtraction.java @@ -0,0 +1,42 @@ +class Solution { + public String fractionAddition(String expression) { + int numerator = 0; + int denominator = 1; + int idx = 0; + int n = expression.length(); + while (idx < n) { + int currNumerator = 0; + int currDenominator = 0; + boolean negative = false; + if (expression.charAt(idx) == '-' || expression.charAt(idx) == '+') { + negative = expression.charAt(idx) == '-' ? true : false; + idx++; + } + while (Character.isDigit(expression.charAt(idx))) { + currNumerator = currNumerator * 10 + Character.getNumericValue(expression.charAt(idx)); + idx++; + } + if (negative) { + currNumerator *= -1; + } + idx++; + while (idx < n && Character.isDigit(expression.charAt(idx))) { + currDenominator = currDenominator * 10 + Character.getNumericValue(expression.charAt(idx)); + idx++; + } + numerator = numerator * currDenominator + currNumerator * denominator; + denominator = denominator * currDenominator; + } + int gcd = Math.abs(gcd(numerator, denominator)); + numerator /= gcd; + denominator /= gcd; + return numerator + "/" + denominator; + } + + private int gcd(int a, int b) { + if (a == 0) { + return b; + } + return gcd(b % a, a); + } +} diff --git a/Medium/Fraction to Recurring Decimal.java b/Medium/Fraction to Recurring Decimal.java index 8e0385ba..dda64d6b 100644 --- a/Medium/Fraction to Recurring Decimal.java +++ b/Medium/Fraction to Recurring Decimal.java @@ -4,22 +4,22 @@ public String fractionToDecimal(int numerator, int denominator) { return "0"; } StringBuilder fraction = new StringBuilder(); - if (numerator < 0 ^ denominator < 0) { - fraction.append("-"); + if ((numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0)) { + fraction.append('-'); } - long dividend = Math.abs((long) numerator); - long divisor = Math.abs((long) denominator); + long dividend = Math.abs(Long.valueOf(numerator)); + long divisor = Math.abs(Long.valueOf(denominator)); fraction.append(String.valueOf(dividend / divisor)); long remainder = dividend % divisor; if (remainder == 0) { return fraction.toString(); } - fraction.append("."); + fraction.append('.'); Map map = new HashMap<>(); while (remainder != 0) { if (map.containsKey(remainder)) { fraction.insert(map.get(remainder), "("); - fraction.append(")"); + fraction.append(')'); break; } map.put(remainder, fraction.length()); diff --git a/Medium/Frequency Tracker.java b/Medium/Frequency Tracker.java new file mode 100644 index 00000000..e5e83453 --- /dev/null +++ b/Medium/Frequency Tracker.java @@ -0,0 +1,48 @@ +class FrequencyTracker { + + private final Map numToFrequencyMapping; + private final Map> frequencyToNumMapping; + + public FrequencyTracker() { + this.numToFrequencyMapping = new HashMap<>(); + this.frequencyToNumMapping = new HashMap<>(); + } + + public void add(int number) { + int prevFrequency = this.numToFrequencyMapping.getOrDefault(number, 0); + int newFrequency = prevFrequency + 1; + this.numToFrequencyMapping.put(number, newFrequency); + updateFreqToNumMapping(number, prevFrequency, newFrequency); + } + + public void deleteOne(int number) { + int prevFrequency = this.numToFrequencyMapping.getOrDefault(number, 0); + if (prevFrequency == 0) { + return; + } + int newFrequency = prevFrequency - 1; + this.numToFrequencyMapping.put(number, newFrequency); + updateFreqToNumMapping(number, prevFrequency, newFrequency); + } + + public boolean hasFrequency(int frequency) { + return this.frequencyToNumMapping.getOrDefault(frequency, new HashSet<>()).size() > 0; + } + + private void updateFreqToNumMapping(int number, int prevFrequency, int newFrequency) { + if (prevFrequency != 0) { + this.frequencyToNumMapping.get(prevFrequency).remove(number); + } + if (newFrequency != 0) { + this.frequencyToNumMapping.computeIfAbsent(newFrequency, k -> new HashSet<>()).add(number); + } + } +} + +/** + * Your FrequencyTracker object will be instantiated and called as such: + * FrequencyTracker obj = new FrequencyTracker(); + * obj.add(number); + * obj.deleteOne(number); + * boolean param_3 = obj.hasFrequency(frequency); + */ diff --git a/Medium/Friends Of Appropriate Ages.java b/Medium/Friends Of Appropriate Ages.java new file mode 100644 index 00000000..8d63064c --- /dev/null +++ b/Medium/Friends Of Appropriate Ages.java @@ -0,0 +1,17 @@ +class Solution { + public int numFriendRequests(int[] ages) { + Map map = new HashMap<>(); + for (int age : ages) { + map.put(age, map.getOrDefault(age, 0) + 1); + } + int totalFriendRequests = 0; + for (Integer ageOne : map.keySet()) { + for (Integer ageTwo : map.keySet()) { + if (!((ageTwo <= 0.5 * ageOne + 7) || (ageTwo > ageOne) || (ageTwo > 100 && ageOne < 100))) { + totalFriendRequests += map.get(ageOne) * (map.get(ageTwo) - (ageOne == ageTwo ? 1 : 0)); + } + } + } + return totalFriendRequests; + } +} diff --git a/Medium/Fruit Into Baskets.java b/Medium/Fruit Into Baskets.java index ad4dba0b..937fbbe9 100644 --- a/Medium/Fruit Into Baskets.java +++ b/Medium/Fruit Into Baskets.java @@ -1,22 +1,21 @@ class Solution { - public int totalFruit(int[] tree) { - Map map = new HashMap<>(); - int maxCount = 0; - int start = 0; - int end = 0; - int n = tree.length; - while (end < n) { - map.put(tree[end], map.getOrDefault(tree[end], 0) + 1); - while (map.size() > 2) { - map.put(tree[start], map.get(tree[start]) - 1); - if (map.get(tree[start]) == 0) { - map.remove(tree[start]); + public int totalFruit(int[] fruits) { + int maximumFruits = 0; + Map map = new HashMap<>(); + int start = 0; + int end = 0; + while (end < fruits.length) { + map.put(fruits[end], map.getOrDefault(fruits[end], 0) + 1); + end++; + while (start < end && map.size() > 2) { + map.put(fruits[start], map.get(fruits[start]) - 1); + if (map.get(fruits[start]) == 0) { + map.remove(fruits[start]); + } + start++; + } + maximumFruits = Math.max(maximumFruits, end - start); } - start++; - } - end++; - maxCount = Math.max(maxCount, end - start); + return maximumFruits; } - return maxCount; - } } diff --git a/Medium/Furthest Building You Can Reach.java b/Medium/Furthest Building You Can Reach.java new file mode 100644 index 00000000..1e110678 --- /dev/null +++ b/Medium/Furthest Building You Can Reach.java @@ -0,0 +1,20 @@ +class Solution { + public int furthestBuilding(int[] heights, int bricks, int ladders) { + PriorityQueue pq = new PriorityQueue<>((a, b) -> b - a); + for (int i = 1; i < heights.length; i++) { + int diff = heights[i] - heights[i - 1]; + if (diff > 0) { + pq.add(diff); + bricks -= diff; + if (bricks < 0) { + if (ladders == 0) { + return i - 1; + } + ladders--; + bricks += pq.poll(); + } + } + } + return heights.length - 1; + } +} diff --git a/Medium/Game of Life.java b/Medium/Game of Life.java index b1cc147d..4341ee13 100644 --- a/Medium/Game of Life.java +++ b/Medium/Game of Life.java @@ -1,39 +1,48 @@ class Solution { - int[][] dirs = {{1, 0}, {0, 1}, {1, 1}, {-1, -1}, {-1, 0}, {0, -1}, {1, -1}, {-1, 1}}; + + private static final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; + public void gameOfLife(int[][] board) { int rows = board.length; int cols = board[0].length; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { - int count = getLiveNeighbourCount(board, i, j); + int liveNeighborCount = getLiveNeighbours(board, i, j); if (board[i][j] == 1) { - if (count < 2 || count > 3) { - board[i][j] = -1; - } - } - else { - if (count == 3) { + if (liveNeighborCount < 2 || liveNeighborCount > 3) { board[i][j] = 2; } + } else { + if (liveNeighborCount == 3) { + board[i][j] = 3; + } } } } for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { - board[i][j] = board[i][j] > 0 ? 1 : 0; + if (board[i][j] == 2) { + board[i][j] = 0; + } else if (board[i][j] == 3) { + board[i][j] = 1; + } } } } - private int getLiveNeighbourCount(int[][] board, int x, int y) { + private static int getLiveNeighbours(int[][] board, int i, int j) { int count = 0; - for (int[] dir : dirs) { - int newX = x + dir[0]; - int newY = y + dir[1]; - if (newX >= 0 && newX < board.length && newY >= 0 && newY < board[0].length && Math.abs(board[newX][newY]) == 1) { + for (int[] dir : DIRS) { + int x = i + dir[0]; + int y = j + dir[1]; + if (isValidCell(board, x, y) && (board[x][y] == 1 || board[x][y] == 2)) { count++; } } return count; } + + private static boolean isValidCell(int[][] board, int i, int j) { + return i >= 0 && j >= 0 && i < board.length && j < board[0].length; + } } diff --git a/Medium/Generate Parentheses.java b/Medium/Generate Parentheses.java index 7b311c92..5d22b059 100644 --- a/Medium/Generate Parentheses.java +++ b/Medium/Generate Parentheses.java @@ -1,30 +1,28 @@ class Solution { - Set set; public List generateParenthesis(int n) { - set = new HashSet<>(); - StringBuilder sb = new StringBuilder(); - helper(n, 0, 0, sb); - return new ArrayList<>(set); + List result = new ArrayList<>(); + helper(result, 0, 0, n, new StringBuilder()); + return result; } - private void helper(int n, int open, int close, StringBuilder sb) { - if (sb.length() == 2 * n) { - set.add(sb.toString()); - } - else { - if (open <= close) { - sb.append('('); - helper(n, open + 1, close, new StringBuilder(sb.toString())); - } - else { - sb.append(')'); - helper(n, open, close + 1, new StringBuilder(sb.toString())); - sb.deleteCharAt(sb.length() - 1); - if (open < n) { - sb.append('('); - helper(n, open + 1, close, new StringBuilder(sb.toString())); - } + private void helper(List result, int start, int end, int n, StringBuilder sb) { + if (start + end == 2 * n) { + if (start == end) { + result.add(new StringBuilder(sb.toString()).toString()); } + return; + } + if (start > end) { + sb.append('('); + helper(result, start + 1, end, n, sb); + sb.deleteCharAt(sb.length() - 1); + sb.append(')'); + helper(result, start, end + 1, n, sb); + sb.deleteCharAt(sb.length() - 1); + } else if (start == end) { + sb.append('('); + helper(result, start + 1, end, n, sb); + sb.deleteCharAt(sb.length() - 1); } } } diff --git a/Medium/Graph Valid Tree.java b/Medium/Graph Valid Tree.java index 7b35c66f..658608a4 100644 --- a/Medium/Graph Valid Tree.java +++ b/Medium/Graph Valid Tree.java @@ -2,31 +2,26 @@ class Solution { public boolean validTree(int n, int[][] edges) { Map> map = new HashMap<>(); for (int[] edge : edges) { - map.computeIfAbsent(edge[1], k -> new HashSet<>()).add(edge[0]); map.computeIfAbsent(edge[0], k -> new HashSet<>()).add(edge[1]); + map.computeIfAbsent(edge[1], k -> new HashSet<>()).add(edge[0]); } - Queue queue = new LinkedList<>(); - int[] visited = new int[n]; - queue.add(0); - visited[0] = 1; - while (!queue.isEmpty()) { - Integer removed = queue.remove(); - for (Integer connection : map.getOrDefault(removed, new HashSet<>())) { - if (visited[connection] == 1) { - return false; + Map parent = new HashMap<>(); + parent.put(0, -1); + Stack stack = new Stack<>(); + stack.push(0); + while (!stack.isEmpty()) { + int node = stack.pop(); + for (int neighbor : map.getOrDefault(node, new HashSet<>())) { + if (parent.get(node) == neighbor) { + continue; } - if (visited[connection] == 0) { - visited[connection] = 1; - queue.add(connection); + if (parent.containsKey(neighbor)) { + return false; } - } - visited[removed] = 2; - } - for (int node : visited) { - if (node == 0) { - return false; + stack.push(neighbor); + parent.put(neighbor, node); } } - return true; + return parent.size() == n; } } diff --git a/Medium/Group Anagrams.java b/Medium/Group Anagrams.java index 3ce07c65..deca920f 100644 --- a/Medium/Group Anagrams.java +++ b/Medium/Group Anagrams.java @@ -1,19 +1,14 @@ class Solution { public List> groupAnagrams(String[] strs) { - Map> map = new HashMap<>(); - for (String str : strs) { - String key = getKey(str); - map.computeIfAbsent(key, k -> new ArrayList<>()).add(str); - } - List> ans = new ArrayList<>(map.values()); - return ans; + return new ArrayList<>( + Arrays.stream(strs).collect(Collectors.groupingBy(Solution::getCodedString)).values()); } - - private String getKey(String s) { - int[] counter = new int[26]; - for (char c : s.toCharArray()) { - counter[c - 'a']++; - } - return Arrays.toString(counter); + + public static String getCodedString(String s) { + return s.chars() + .mapToObj(c -> (char) c) + .sorted() + .map(Object::toString) + .collect(Collectors.joining()); } } diff --git a/Medium/Group Shifted Strings.java b/Medium/Group Shifted Strings.java index 2207727c..b1209bbf 100644 --- a/Medium/Group Shifted Strings.java +++ b/Medium/Group Shifted Strings.java @@ -1,19 +1,17 @@ class Solution { public List> groupStrings(String[] strings) { Map> map = new HashMap<>(); - for (String str : strings) { - map.computeIfAbsent(getKey(str), k -> new ArrayList<>()).add(str); + for (String s : strings) { + map.computeIfAbsent(getShiftedCode(s), k -> new ArrayList<>()).add(s); } return new ArrayList<>(map.values()); } - - private String getKey(String s) { - StringBuilder sb = new StringBuilder(); + + private String getShiftedCode(String s) { + StringBuilder key = new StringBuilder(); for (int i = 1; i < s.length(); i++) { - int diff = s.charAt(i) - s.charAt(i - 1); - diff = diff < 0 ? diff + 26 : diff; - sb.append(diff); + key.append(String.format("%2d", (s.charAt(i) - s.charAt(i-1) + 26) % 26)); } - return sb.toString(); + return key.toString(); } } diff --git a/Medium/Group the People Given the Group Size They Belong To.java b/Medium/Group the People Given the Group Size They Belong To.java index 003f6099..095fb67f 100644 --- a/Medium/Group the People Given the Group Size They Belong To.java +++ b/Medium/Group the People Given the Group Size They Belong To.java @@ -1,27 +1,18 @@ class Solution { public List> groupThePeople(int[] groupSizes) { - Map>> map = new HashMap<>(); - int n = groupSizes.length; - for (int i = 0; i < n; i++) { - int size = groupSizes[i]; - if (!map.containsKey(size)) { - map.put(size, new ArrayList<>()); - map.get(size).add(new ArrayList<>()); - } - int arraySize = map.get(size).size(); - if (map.get(size).get(arraySize - 1).size() == size) { - map.get(size).add(new ArrayList<>()); - arraySize++; - } - map.get(size).get(arraySize - 1).add(i); + Map> map = new HashMap<>(); + for (int i = 0; i < groupSizes.length; i++) { + map.computeIfAbsent(groupSizes[i], k -> new ArrayList<>()).add(i); } - List> ans = new ArrayList<>(); + List> result = new ArrayList<>(); for (Integer key : map.keySet()) { - List> lists = map.get(key); - for (List list : lists) { - ans.add(list); + List candidates = map.get(key); + int idx = 0; + while (idx < candidates.size()) { + result.add(candidates.subList(idx, idx + key)); + idx += key; } } - return ans; + return result; } } diff --git a/Medium/Grumpy Bookstore Owner.java b/Medium/Grumpy Bookstore Owner.java index ac064c2a..996ac4d0 100644 --- a/Medium/Grumpy Bookstore Owner.java +++ b/Medium/Grumpy Bookstore Owner.java @@ -1,19 +1,16 @@ class Solution { - public int maxSatisfied(int[] customers, int[] grumpy, int X) { - int totalSum = 0; - int maxDiff = 0; - int grumpySum = 0; - - for (int i = 0; i < customers.length; i++) { - totalSum += grumpy[i] == 1 ? 0 : customers[i]; - grumpySum += grumpy[i] == 1 ? customers[i] : 0; - if (i >= X) { - grumpySum -= grumpy[i - X] == 1 ? customers[i - X] : 0; - } - - maxDiff = Math.max(maxDiff, grumpySum); - } - - return totalSum + maxDiff; + public int maxSatisfied(int[] customers, int[] grumpy, int minutes) { + int totalSum = 0; + int maxDiff = 0; + int grumpySum = 0; + for (int i = 0; i < customers.length; i++) { + totalSum += grumpy[i] == 1 ? 0 : customers[i]; + grumpySum += grumpy[i] == 1 ? customers[i] : 0; + if (i >= minutes) { + grumpySum -= grumpy[i - minutes] == 1 ? customers[i - minutes] : 0; + } + maxDiff = Math.max(maxDiff, grumpySum); } + return totalSum + maxDiff; + } } diff --git a/Medium/Hand of Straights.java b/Medium/Hand of Straights.java index ceff444a..5f407cf0 100644 --- a/Medium/Hand of Straights.java +++ b/Medium/Hand of Straights.java @@ -1,29 +1,32 @@ class Solution { - public boolean isNStraightHand(int[] hand, int W) { - if (hand.length % W != 0) { - return false; - } - Map counterMap = new HashMap<>(); - Set set = new TreeSet<>(); - for (int num : hand) { - counterMap.put(num, counterMap.getOrDefault(num, 0) + 1); - set.add(num); - } - Iterator iter = set.iterator(); - Integer curr = iter.next(); - while (counterMap.get(curr) > 0) { - int temp = curr; - for (int i = 0; i < W; i++) { - if (counterMap.getOrDefault(temp, 0) == 0) { - return false; + public boolean isNStraightHand(int[] hand, int groupSize) { + if (hand.length % groupSize != 0) { + return false; + } + Map map = new HashMap<>(); + for (int num : hand) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + PriorityQueue pq = new PriorityQueue<>(map.keySet()); + while (!pq.isEmpty()) { + List temp = new ArrayList<>(); + int prev = -1; + for (int i = 0; i < groupSize; i++) { + if (pq.isEmpty()) { + return false; + } + int removed = pq.remove(); + map.put(removed, map.get(removed) - 1); + if (map.get(removed) > 0) { + temp.add(removed); + } + if (prev != -1 && removed != prev + 1) { + return false; + } + prev = removed; + } + pq.addAll(temp); } - counterMap.put(temp, counterMap.get(temp) - 1); - temp++; - } - while (iter.hasNext() && counterMap.get(curr) == 0) { - curr = iter.next(); - } + return true; } - return true; - } } diff --git a/Medium/High-Access Employees.java b/Medium/High-Access Employees.java new file mode 100644 index 00000000..8c881fc8 --- /dev/null +++ b/Medium/High-Access Employees.java @@ -0,0 +1,43 @@ +class Solution { + public List findHighAccessEmployees(List> accessTimeEntries) { + Map> map = new HashMap<>(); + for (List entry : accessTimeEntries) { + String employee = entry.get(0); + String time = entry.get(1); + map.computeIfAbsent(employee, k -> new ArrayList<>()).add(TimeRecord.buildTimeRecord(time)); + } + List result = new ArrayList<>(); + for (String key : map.keySet()) { + List entries = map.get(key); + if (entries.size() < 3) { + continue; + } + Collections.sort(entries); + for (int i = 0; i < entries.size() - 2; i++) { + if (TimeRecord.areWithinSameHour(entries.get(i), entries.get(i + 2))) { + result.add(key); + break; + } + } + } + return result; + } + + private record TimeRecord(int totalMinutes) implements Comparable { + + public static TimeRecord buildTimeRecord(String entry) { + int hour = Integer.parseInt(entry.substring(0, 2)); + int min = Integer.parseInt(entry.substring(2)); + return new TimeRecord(hour * 60 + min); + } + + public static boolean areWithinSameHour(TimeRecord startTime, TimeRecord endTime) { + return endTime.totalMinutes - startTime.totalMinutes < 60; + } + + @Override + public int compareTo(TimeRecord o) { + return this.totalMinutes - o.totalMinutes; + } + } +} diff --git a/Medium/House Robber II.java b/Medium/House Robber II.java new file mode 100644 index 00000000..5219984e --- /dev/null +++ b/Medium/House Robber II.java @@ -0,0 +1,20 @@ +class Solution { + public int rob(int[] nums) { + if (nums.length == 1) { + return nums[0]; + } + return Math.max(robHelper(nums, 0, nums.length - 2), robHelper(nums, 1, nums.length - 1)); + } + + private int robHelper(int[] nums, int lower, int higher) { + int include = 0; + int exclude = 0; + for (int j = lower; j <= higher; j++) { + int includeIdx = include; + int excludeIdx = exclude; + include = excludeIdx + nums[j]; + exclude = Math.max(excludeIdx, includeIdx); + } + return Math.max(include, exclude); + } +} diff --git a/Medium/House Robber III.java b/Medium/House Robber III.java new file mode 100644 index 00000000..924423a9 --- /dev/null +++ b/Medium/House Robber III.java @@ -0,0 +1,32 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public int rob(TreeNode root) { + int[] ans = helper(root); + return Math.max(ans[0], ans[1]); + } + + private int[] helper(TreeNode root) { + if (root == null) { + return new int[]{0, 0}; + } + int[] left = helper(root.left); + int[] right = helper(root.right); + int robbed = root.val + left[1] + right[1]; + int notRobbed = Math.max(left[0], left[1]) + Math.max(right[0], right[1]); + return new int[]{robbed, notRobbed}; + } +} diff --git a/Medium/House Robber.java b/Medium/House Robber.java new file mode 100644 index 00000000..3ebdc59b --- /dev/null +++ b/Medium/House Robber.java @@ -0,0 +1,11 @@ +class Solution { + public int rob(int[] nums) { + int n = nums.length; + int[] dp = new int[n + 1]; + dp[1] = nums[0]; + for (int i = 1; i < n; i++) { + dp[i + 1] = Math.max(dp[i], dp[i - 1] + nums[i]); + } + return dp[n]; + } +} diff --git a/Medium/Image Overlap.java b/Medium/Image Overlap.java new file mode 100644 index 00000000..680b1750 --- /dev/null +++ b/Medium/Image Overlap.java @@ -0,0 +1,29 @@ +class Solution { + public int largestOverlap(int[][] img1, int[][] img2) { + List> nonZeroCoordinates1 = getNonZeroCoordinates(img1); + List> nonZeroCoordinates2 = getNonZeroCoordinates(img2); + int maxOverlap = 0; + Map, Integer> groupCount = new HashMap<>(); + for (Pair c1 : nonZeroCoordinates1) { + for (Pair c2 : nonZeroCoordinates2) { + Pair vector = new Pair( + c2.getKey() - c1.getKey(), c2.getValue() - c1.getValue()); + groupCount.put(vector, groupCount.getOrDefault(vector, 0) + 1); + maxOverlap = Math.max(maxOverlap, groupCount.get(vector)); + } + } + return maxOverlap; + } + + private List> getNonZeroCoordinates(int[][] arr) { + List> coordinates = new ArrayList<>(); + for (int i = 0; i < arr.length; i++) { + for (int j = 0; j < arr[0].length; j++) { + if (arr[i][j] == 1) { + coordinates.add(new Pair(i, j)); + } + } + } + return coordinates; + } +} diff --git a/Medium/Implement Trie (Prefix Tree).java b/Medium/Implement Trie (Prefix Tree).java index f987662b..353634fd 100644 --- a/Medium/Implement Trie (Prefix Tree).java +++ b/Medium/Implement Trie (Prefix Tree).java @@ -1,71 +1,55 @@ +import java.util.Optional; + class Trie { - /** Initialize your data structure here. */ - Node root; - public Trie() { - root = new Node('-'); - } + private final TrieNode root; - /** Inserts a word into the trie. */ - public void insert(String word) { - insertHelper(word, 0, root); - } - - private void insertHelper(String word, int idx, Node root) { - if (idx >= word.length()) { - root.isWord = true; - return; - } - if (!root.children.containsKey(word.charAt(idx))) { - root.children.put(word.charAt(idx), new Node(word.charAt(idx))); + public Trie() { + root = new TrieNode(); } - root = root.children.get(word.charAt(idx)); - insertHelper(word, idx + 1, root); - } - /** Returns if the word is in the trie. */ - public boolean search(String word) { - return searchHelper(word, 0, root); - } - - private boolean searchHelper(String word, int idx, Node root) { - if (idx == word.length()) { - return root.isWord; + public void insert(String word) { + TrieNode curr = root; + for (char c : word.toCharArray()) { + if (!curr.children.containsKey(c)) { + curr.children.put(c, new TrieNode()); + } + curr = curr.children.get(c); + } + curr.isWord = true; } - if (!root.children.containsKey(word.charAt(idx))) { - return false; + + public boolean search(String word) { + Optional node = searchHelper(word); + return node.isPresent() && node.get().isWord; } - root = root.children.get(word.charAt(idx)); - return searchHelper(word, idx + 1, root); - } - /** Returns if there is any word in the trie that starts with the given prefix. */ - public boolean startsWith(String prefix) { - return startsWithHelper(prefix, 0, root); - } - - private boolean startsWithHelper(String word, int idx, Node root) { - if (idx == word.length()) { - return true; + public boolean startsWith(String prefix) { + Optional node = searchHelper(prefix); + return node.isPresent(); } - if (!root.children.containsKey(word.charAt(idx))) { - return false; + + public Optional searchHelper(String word) { + TrieNode curr = root; + for (char c : word.toCharArray()) { + if (!curr.children.containsKey(c)) { + return Optional.empty(); + } + curr = curr.children.get(c); + } + return Optional.of(curr); } - root = root.children.get(word.charAt(idx)); - return startsWithHelper(word, idx + 1, root); - } -} -class Node { - char val; - Map children; - boolean isWord; - - public Node(char val) { - this.val = val; - children = new HashMap<>(); - isWord = false; - } + private static class TrieNode { + + private final Map children; + private boolean isWord; + + private TrieNode() { + this.children = new HashMap<>(); + this.isWord = false; + } + } } /** diff --git a/Medium/Implement Trie II (Prefix Tree).java b/Medium/Implement Trie II (Prefix Tree).java new file mode 100644 index 00000000..7c5b1a36 --- /dev/null +++ b/Medium/Implement Trie II (Prefix Tree).java @@ -0,0 +1,76 @@ +import java.util.Optional; + + +class Trie { + + private final Node root; + + public Trie() { + root = new Node(); + } + + public void insert(String word) { + Node curr = root; + for (char c : word.toCharArray()) { + if (!curr.children.containsKey(c)) { + curr.children.put(c, new Node()); + } + curr = curr.children.get(c); + curr.startingWordCount++; + } + curr.endingWordCount++; + } + + public int countWordsEqualTo(String word) { + Optional curr = search(word); + return curr.map(node -> node.endingWordCount).orElse(0); + } + + public int countWordsStartingWith(String prefix) { + Optional curr = search(prefix); + return curr.map(node -> node.startingWordCount).orElse(0); + } + + public void erase(String word) { + Node curr = root; + for (char c : word.toCharArray()) { + curr = curr.children.get(c); + curr.startingWordCount--; + } + curr.endingWordCount--; + } + + private Optional search(String word) { + Node curr = root; + for (char c : word.toCharArray()) { + if (!curr.children.containsKey(c)) { + return Optional.empty(); + } + curr = curr.children.get(c); + } + return Optional.of(curr); + } + + private static class Node { + + private int startingWordCount; + private int endingWordCount; + + private final Map children; + + public Node() { + this.startingWordCount = 0; + this.endingWordCount = 0; + this.children = new HashMap<>(); + } + } +} + +/** + * Your Trie object will be instantiated and called as such: + * Trie obj = new Trie(); + * obj.insert(word); + * int param_2 = obj.countWordsEqualTo(word); + * int param_3 = obj.countWordsStartingWith(prefix); + * obj.erase(word); + */ diff --git a/Medium/Increasing Triplet Subsequence.java b/Medium/Increasing Triplet Subsequence.java index 53e09710..9facec89 100644 --- a/Medium/Increasing Triplet Subsequence.java +++ b/Medium/Increasing Triplet Subsequence.java @@ -5,11 +5,9 @@ public boolean increasingTriplet(int[] nums) { for (int num : nums) { if (num <= firstNum) { firstNum = num; - } - else if (num <= secondNum) { + } else if (num <= secondNum) { secondNum = num; - } - else { + } else { return true; } } diff --git a/Medium/Incremental Memory Leak.java b/Medium/Incremental Memory Leak.java new file mode 100644 index 00000000..7db5de79 --- /dev/null +++ b/Medium/Incremental Memory Leak.java @@ -0,0 +1,13 @@ +class Solution { + public int[] memLeak(int memory1, int memory2) { + int currentLeak = 1; + while (Math.max(memory1, memory2) >= currentLeak) { + if (memory1 >= memory2) { + memory1 -= currentLeak++; + } else { + memory2 -= currentLeak++; + } + } + return new int[]{currentLeak, memory1, memory2}; + } +} diff --git a/Medium/Inorder Successor in BST II.java b/Medium/Inorder Successor in BST II.java index d6810587..e8c672df 100644 --- a/Medium/Inorder Successor in BST II.java +++ b/Medium/Inorder Successor in BST II.java @@ -10,9 +10,6 @@ class Node { class Solution { public Node inorderSuccessor(Node node) { - if (node == null) { - return null; - } if (node.right != null) { Node rightNode = node.right; while (rightNode.left != null) { @@ -20,17 +17,13 @@ public Node inorderSuccessor(Node node) { } return rightNode; } - else { - Node curr = node; - Node parentNode = node.parent; - while (parentNode != null) { - if (parentNode.left == curr) { - return parentNode; - } - curr = parentNode; - parentNode = parentNode.parent; + while (node.parent != null) { + Node parent = node.parent; + if (parent.left == node) { + return parent; } + node = parent; } - return null; - } + return null; + } } diff --git a/Medium/Inorder Successor in BST.java b/Medium/Inorder Successor in BST.java index 62b37697..f7fb5702 100644 --- a/Medium/Inorder Successor in BST.java +++ b/Medium/Inorder Successor in BST.java @@ -10,24 +10,21 @@ class Solution { public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { if (p.right != null) { - TreeNode node = p.right; - while (node.left != null) { - node = node.left; + TreeNode rightNode = p.right; + while (rightNode != null && rightNode.left != null) { + rightNode = rightNode.left; } - return node; + return rightNode; } - else { - TreeNode lastLeft = null; - while (root != p) { - if (root.val > p.val) { - lastLeft = root; - root = root.left; - } - else { - root = root.right; - } + TreeNode prev = null; + while (root != p) { + if (root.val > p.val) { + prev = root; + root = root.left; + } else { + root = root.right; } - return lastLeft; } + return prev; } } diff --git a/Medium/Insert Delete GetRandom O(1).java b/Medium/Insert Delete GetRandom O(1).java index 1149d866..9ef0fc92 100644 --- a/Medium/Insert Delete GetRandom O(1).java +++ b/Medium/Insert Delete GetRandom O(1).java @@ -1,42 +1,41 @@ class RandomizedSet { - /** Initialize your data structure here. */ - Map map; - List list; - public RandomizedSet() { - map = new HashMap<>(); - list = new ArrayList<>(); - } + private final List values; + private final Map valToIndexMap; - /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ - public boolean insert(int val) { - if (map.containsKey(val)) { - return false; + public RandomizedSet() { + this.values = new ArrayList<>(); + this.valToIndexMap = new HashMap<>(); } - list.add(val); - map.put(val, list.size() - 1); - return true; - } - /** Removes a value from the set. Returns true if the set contained the specified element. */ - public boolean remove(int val) { - if (!map.containsKey(val)) { - return false; + public boolean insert(int val) { + if (valToIndexMap.containsKey(val)) { + return false; + } + values.add(val); + valToIndexMap.put(val, values.size() - 1); + return true; } - int idx = map.get(val); - int lastIdx = list.size() - 1; - list.set(idx, list.get(lastIdx)); - map.put(list.get(lastIdx), idx); - map.remove(val); - list.remove(lastIdx); - return true; - } - /** Get a random element from the set. */ - public int getRandom() { - int idx = new Random().nextInt(list.size()); - return list.get(idx); - } + public boolean remove(int val) { + if (!valToIndexMap.containsKey(val)) { + return false; + } + int valIdx = valToIndexMap.get(val); + int valAtLastIdx = values.get(values.size() - 1); + // update index for last element + values.set(valIdx, valAtLastIdx); + valToIndexMap.put(valAtLastIdx, valIdx); + // remove value + values.remove(values.size() - 1); + valToIndexMap.remove(val); + return true; + } + + public int getRandom() { + int idx = new Random().nextInt(values.size()); + return values.get(idx); + } } /** diff --git a/Medium/Insert Greatest Common Divisors in Linked List.java b/Medium/Insert Greatest Common Divisors in Linked List.java new file mode 100644 index 00000000..6dcf5fd0 --- /dev/null +++ b/Medium/Insert Greatest Common Divisors in Linked List.java @@ -0,0 +1,29 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode insertGreatestCommonDivisors(ListNode head) { + ListNode curr = head; + while (curr != null && curr.next != null) { + ListNode gcdNode = new ListNode(findGcd(curr.val, curr.next.val)); + gcdNode.next = curr.next; + curr.next = gcdNode; + curr = gcdNode.next; + } + return head; + } + + private static int findGcd(int numOne, int numTwo) { + if (numOne == numTwo) { + return numOne; + } + return numOne > numTwo ? findGcd(numOne - numTwo, numTwo) : findGcd(numOne, numTwo - numOne); + } +} diff --git a/Medium/Insert Interval.java b/Medium/Insert Interval.java new file mode 100644 index 00000000..a90a6884 --- /dev/null +++ b/Medium/Insert Interval.java @@ -0,0 +1,19 @@ +class Solution { + public int[][] insert(int[][] intervals, int[] newInterval) { + List result = new ArrayList<>(); + int idx = 0; + while (idx < intervals.length && intervals[idx][1] < newInterval[0]) { + result.add(intervals[idx++]); + } + while (idx < intervals.length && newInterval[1] >= intervals[idx][0]) { + newInterval[0] = Math.min(newInterval[0], intervals[idx][0]); + newInterval[1] = Math.max(newInterval[1], intervals[idx][1]); + idx++; + } + result.add(newInterval); + while (idx < intervals.length) { + result.add(intervals[idx++]); + } + return result.toArray(new int[result.size()][]); + } +} diff --git a/Medium/Insert into a Binary Search Tree.java b/Medium/Insert into a Binary Search Tree.java index 30e5ce41..c7d1015b 100644 --- a/Medium/Insert into a Binary Search Tree.java +++ b/Medium/Insert into a Binary Search Tree.java @@ -15,15 +15,24 @@ */ class Solution { public TreeNode insertIntoBST(TreeNode root, int val) { - if (root == null) { - return new TreeNode(val); + TreeNode node = root; + while (node != null) { + if (val > node.val) { + if (node.right == null) { + node.right = new TreeNode(val); + return root; + } else { + node = node.right; + } + } else { + if (node.left == null) { + node.left = new TreeNode(val); + return root; + } else { + node = node.left; + } + } } - if (root.val < val) { - root.right = insertIntoBST(root.right, val); - } - else { - root.left = insertIntoBST(root.left, val); - } - return root; + return new TreeNode(val); } } diff --git a/Medium/Integer Break.java b/Medium/Integer Break.java new file mode 100644 index 00000000..10071c6f --- /dev/null +++ b/Medium/Integer Break.java @@ -0,0 +1,19 @@ +class Solution { + public int integerBreak(int n) { + if (n < 4) { + return n - 1; + } + int[] dp = new int[n + 1]; + for (int i = 1; i <= 3; i++) { + dp[i] = i; + } + for (int i = 4; i <= n; i++) { + int result = i; + for (int j = 2; j < i; j++) { + result = Math.max(result, j * dp[i - j]); + } + dp[i] = result; + } + return dp[n]; + } +} diff --git a/Medium/Integer To Roman.java b/Medium/Integer To Roman.java index 327be29a..33de2ba3 100644 --- a/Medium/Integer To Roman.java +++ b/Medium/Integer To Roman.java @@ -1,17 +1,20 @@ class Solution { - public String intToRoman(int num) { - int[] values = {1000,900,500,400,100,90,50,40,10,9,5,4,1}; - String[] strs = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"}; - - StringBuilder sb = new StringBuilder(); - - for (int i = 0; i < values.length; i++) { - while (num >= values[i]) { - num -= values[i]; - sb.append(strs[i]); - } + + private static final int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; + private static final String[] symbols = { + "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; + + public String intToRoman(int num) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < values.length && num > 0; i++) { + int factor = num / values[i]; + num %= values[i]; + if (factor > 0) { + for (int j = 1; j <= factor; j++) { + sb.append(symbols[i]); } - - return sb.toString(); + } } + return sb.toString(); + } } diff --git a/Medium/Interleaving String.java b/Medium/Interleaving String.java new file mode 100644 index 00000000..6e4408ce --- /dev/null +++ b/Medium/Interleaving String.java @@ -0,0 +1,24 @@ +class Solution { + public boolean isInterleave(String s1, String s2, String s3) { + if (s1.length() + s2.length() != s3.length()) { + return false; + } + Boolean[][] dp = new Boolean[s1.length()][s2.length()]; + return isInterleaveHelper(s1, 0, s2, 0, s3, 0, dp); + } + + private boolean isInterleaveHelper(String s1, int i1, String s2, int i2, String s3, int i3, Boolean[][] dp) { + if (i1 == s1.length()) { + return s2.substring(i2).equals(s3.substring(i3)); + } + if (i2 == s2.length()) { + return s1.substring(i1).equals(s3.substring(i3)); + } + if (dp[i1][i2] != null) { + return dp[i1][i2]; + } + dp[i1][i2] = (s3.charAt(i3) == s1.charAt(i1) && isInterleaveHelper(s1, i1 + 1, s2, i2, s3, i3 + 1, dp)) || + (s3.charAt(i3) == s2.charAt(i2) && isInterleaveHelper(s1, i1, s2, i2 + 1, s3, i3 + 1, dp)); + return dp[i1][i2]; + } +} diff --git a/Medium/Interval List Intersections.java b/Medium/Interval List Intersections.java index 0b7c1033..6441b8ec 100644 --- a/Medium/Interval List Intersections.java +++ b/Medium/Interval List Intersections.java @@ -1,22 +1,21 @@ class Solution { - public int[][] intervalIntersection(int[][] A, int[][] B) { + public int[][] intervalIntersection(int[][] firstList, int[][] secondList) { List list = new ArrayList<>(); - int startA = 0; - int startB = 0; - while (startA < A.length && startB < B.length) { - int intervalStart = Math.max(A[startA][0], B[startB][0]); - int intervalEnd = Math.min(A[startA][1], B[startB][1]); - if (intervalStart <= intervalEnd) { - list.add(new int[]{intervalStart, intervalEnd}); + int idxOne = 0; + int idxTwo = 0; + while (idxOne < firstList.length && idxTwo < secondList.length) { + int maxStart = Math.max(firstList[idxOne][0], secondList[idxTwo][0]); + int minEnd = Math.min(firstList[idxOne][1], secondList[idxTwo][1]); + if (maxStart <= minEnd) { + list.add(new int[]{maxStart, minEnd}); } - if (A[startA][1] < B[startB][1]) { - startA++; - } - else { - startB++; + if (minEnd == firstList[idxOne][1]) { + idxOne++; + } else { + idxTwo++; } } - int[][] ans = new int[list.size()][2]; - return list.toArray(ans); + int[][] result = new int[list.size()][2]; + return list.toArray(result); } } diff --git a/Medium/Invalid Transactions.java b/Medium/Invalid Transactions.java index 1d0d9b6d..aa48c7db 100644 --- a/Medium/Invalid Transactions.java +++ b/Medium/Invalid Transactions.java @@ -1,46 +1,38 @@ class Solution { public List invalidTransactions(String[] transactions) { - Map> map = new HashMap<>(); - Set invalidTransactions = new HashSet<>(); - for (int i = 0; i < transactions.length; i++) { - String[] details = transactions[i].split(","); - String name = details[0]; - int time = Integer.parseInt(details[1]); - int amount = Integer.parseInt(details[2]); - String city = details[3]; + Set invalidTransactionSet = new HashSet<>(); + Map> map = new HashMap<>(); + Map transactionOccurenceCount = new HashMap<>(); + for (String transactionString : transactions) { + transactionOccurenceCount.put(transactionString, transactionOccurenceCount.getOrDefault(transactionString, 0) + 1); + String[] transaction = transactionString.split(","); + String name = transaction[0]; + int amount = Integer.parseInt(transaction[2]); + String city = transaction[3]; + int time = Integer.parseInt(transaction[1]); if (amount > 1000) { - invalidTransactions.add(transactions[i]); - } - if (map.containsKey(name)) { - List otherTransactions = map.get(name); - for (Transaction transaction : otherTransactions) { - if (!transaction.city.equals(city) && Math.abs(transaction.time - time) <= 60) { - invalidTransactions.add(transactions[transaction.idx]); - invalidTransactions.add(transactions[i]); - } + invalidTransactionSet.add(transactionString); + } + map.computeIfAbsent(name, k -> new ArrayList<>()); + List currentTransactions = map.get(name); + for (String currentTransaction : currentTransactions) { + String currentCity = currentTransaction.split(",")[3]; + int currentTime = Integer.parseInt(currentTransaction.split(",")[1]); + if (!currentCity.equals(city) && Math.abs(time - currentTime) <= 60) { + invalidTransactionSet.add(currentTransaction); + invalidTransactionSet.add(transactionString); } } - map.computeIfAbsent(name, k -> new ArrayList<>()).add( - new Transaction(name, time, amount, city, i) - ); + currentTransactions.add(transactionString); + map.put(name, currentTransactions); } - return new ArrayList<>(invalidTransactions); - } -} - - -class Transaction { - String name; - int time; - int amount; - String city; - int idx; - - public Transaction(String name, int time, int amount, String city, int idx) { - this.name = name; - this.time = time; - this.amount = amount; - this.city = city; - this.idx = idx; + List result = new ArrayList<>(); + for (String trs : invalidTransactionSet) { + int count = transactionOccurenceCount.get(trs); + while (count-- > 0) { + result.add(trs); + } + } + return result; } } diff --git a/Medium/Is Graph Bipartite.java b/Medium/Is Graph Bipartite.java index 23f4e0bf..3a30604f 100644 --- a/Medium/Is Graph Bipartite.java +++ b/Medium/Is Graph Bipartite.java @@ -1,27 +1,38 @@ class Solution { - public boolean isBipartite(int[][] graph) { - int n = graph.length; - int[] color = new int[n]; - Arrays.fill(color, -1); - for (int i = 0; i < n; i++) { - if (color[i] == -1) { - Stack stack = new Stack<>(); - stack.push(i); - color[i] = 0; - while (!stack.isEmpty()) { - Integer node = stack.pop(); - for (Integer neighbor : graph[node]) { - if (color[neighbor] == -1) { - stack.push(neighbor); - color[neighbor] = color[node] ^ 1; + public boolean isBipartite(int[][] graph) { + int n = graph.length; + int[] color = new int[n]; + for (int i = 0; i < n; i++) { + if (color[i] == 0 && !isBipartite(graph, i, color)) { + return false; } - else if (color[neighbor] == color[node]) { - return false; + } + return true; + } + + private boolean isBipartite(int[][] graph, int node, int[] color) { + Queue queue = new LinkedList<>(); + queue.add(node); + int currColor = 1; + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + int removed = queue.remove(); + if (color[removed] != 0) { + if (color[removed] != currColor) { + return false; + } + } else { + color[removed] = currColor; + for (int conn : graph[removed]) { + if (color[conn] == 0) { + queue.add(conn); + } + } + } } - } + currColor = currColor == 1 ? 2 : 1; } - } + return true; } - return true; - } } diff --git a/Medium/Is Subsequence.java b/Medium/Is Subsequence.java deleted file mode 100644 index cde06c72..00000000 --- a/Medium/Is Subsequence.java +++ /dev/null @@ -1,21 +0,0 @@ -class Solution { - public boolean isSubsequence(String s, String t) { - char[] sChar = s.toCharArray(); - char[] tChar = t.toCharArray(); - - int i=0; - int j=0; - int low = s.length(); - int high = t.length(); - - while(i queue = new LinkedList<>(); + Set visited = new HashSet<>(); + queue.add(start); + while (!queue.isEmpty()) { + int size = queue.size(); + for (int i = 0; i < size; i++) { + int removed = queue.remove(); + if (arr[removed] == 0) { + return true; + } + if (visited.contains(removed)) { + continue; + } + visited.add(removed); + if (removed + arr[removed] < arr.length) { + queue.add(removed + arr[removed]); + } + if (removed - arr[removed] >= 0) { + queue.add(removed - arr[removed]); + } + } + } + return false; + } +} diff --git a/Medium/Jump Game VI.java b/Medium/Jump Game VI.java new file mode 100644 index 00000000..76ae982c --- /dev/null +++ b/Medium/Jump Game VI.java @@ -0,0 +1,16 @@ +class Solution { + public int maxResult(int[] nums, int k) { + int[] score = new int[nums.length]; + score[0] = nums[0]; + PriorityQueue queue = new PriorityQueue<>((a, b) -> b[0] - a[0]); + queue.add(new int[]{nums[0], 0}); + for (int i = 1; i < nums.length; i++) { + while (!queue.isEmpty() && queue.peek()[1] < i - k) { + queue.remove(); + } + score[i] = score[queue.peek()[1]] + nums[i]; + queue.add(new int[]{score[i], i}); + } + return score[nums.length - 1]; + } +} diff --git a/Medium/K Closest Points to Origin.java b/Medium/K Closest Points to Origin.java new file mode 100644 index 00000000..4f92b4a6 --- /dev/null +++ b/Medium/K Closest Points to Origin.java @@ -0,0 +1,20 @@ +class Solution { + public int[][] kClosest(int[][] points, int k) { + PriorityQueue pq = new PriorityQueue<>((o1, o2) -> getDistance(o2) - getDistance(o1)); + for (int[] point : points) { + pq.add(point); + if (pq.size() > k) { + pq.poll(); + } + } + int[][] result = new int[pq.size()][2]; + for (int i = 0; i < result.length; i++) { + result[i] = pq.poll(); + } + return result; + } + + private int getDistance(int[] point) { + return (point[0] * point[0]) + (point[1] * point[1]); + } +} diff --git a/Medium/K Radius Subarray Averages.java b/Medium/K Radius Subarray Averages.java new file mode 100644 index 00000000..18cd8995 --- /dev/null +++ b/Medium/K Radius Subarray Averages.java @@ -0,0 +1,24 @@ +class Solution { + public int[] getAverages(int[] nums, int k) { + int[] result = new int[nums.length]; + Arrays.fill(result, -1); + int subarrayLength = 2 * k + 1; + if (subarrayLength > nums.length) { + return result; + } + long sum = 0; + for (int i = 0; i < subarrayLength; i++) { + sum += nums[i]; + } + int startIdx = 0; + int endIdx = subarrayLength; + for (int i = k; i < nums.length - k; i++) { + result[i] = (int) (sum / subarrayLength); + sum -= nums[startIdx++]; + if (endIdx < nums.length) { + sum += nums[endIdx++]; + } + } + return result; + } +} diff --git a/Medium/K-th Symbol in Grammar.java b/Medium/K-th Symbol in Grammar.java new file mode 100644 index 00000000..da370f11 --- /dev/null +++ b/Medium/K-th Symbol in Grammar.java @@ -0,0 +1,18 @@ +class Solution { + public int kthGrammar(int n, int k) { + return depthFirstSearch(n, k, 0); + } + + private int depthFirstSearch(int n, int k, int root) { + if (n == 1) { + return root; + } + int nodeCount = (int) Math.pow(2, n - 1); + if (k > (nodeCount / 2)) { + int nextRoot = (root == 0) ? 1 : 0; + return depthFirstSearch(n - 1, k - (nodeCount / 2), nextRoot); + } + int nextRoot = (root == 0) ? 0 : 1; + return depthFirstSearch(n - 1, k, nextRoot); + } +} diff --git a/Medium/Keys and Rooms.java b/Medium/Keys and Rooms.java index 6a2f8c3f..a4fd783a 100644 --- a/Medium/Keys and Rooms.java +++ b/Medium/Keys and Rooms.java @@ -1,19 +1,18 @@ class Solution { public boolean canVisitAllRooms(List> rooms) { - Stack stack = new Stack<>(); - Set set = new HashSet<>(); - set.add(0); - stack.add(0); - while (!stack.isEmpty()) { - int keyPopped = stack.pop(); - List keys = rooms.get(keyPopped); - for (Integer key : keys) { - if (!set.contains(key)) { - stack.push(key); - set.add(key); + Set visited = new HashSet<>(); + Queue queue = new LinkedList<>(); + queue.add(0); + visited.add(0); + while (!queue.isEmpty()) { + int removed = queue.remove(); + for (Integer nextRoom : rooms.get(removed)) { + if (!visited.contains(nextRoom)) { + queue.add(nextRoom); + visited.add(nextRoom); } } } - return set.size() == rooms.size(); + return visited.size() == rooms.size(); } } diff --git a/Medium/Kill Process.java b/Medium/Kill Process.java index 623bf04f..e0f5cbf7 100644 --- a/Medium/Kill Process.java +++ b/Medium/Kill Process.java @@ -1,25 +1,21 @@ class Solution { public List killProcess(List pid, List ppid, int kill) { - Map> map = new HashMap<>(); + Map> map = new HashMap<>(); for (int i = 0; i < pid.size(); i++) { - if (ppid.get(i) != 0) { - map.computeIfAbsent(ppid.get(i), k -> new ArrayList<>()).add(pid.get(i)); - } + map.computeIfAbsent(ppid.get(i), k -> new HashSet<>()).add(pid.get(i)); } - Set set = new HashSet<>(); - Queue queue = new LinkedList<>(); - queue.add(kill); - set.add(kill); - while (!queue.isEmpty()) { - int removed = queue.remove(); - set.add(removed); - for (Integer child : map.getOrDefault(removed, new ArrayList<>())) { - if (!set.contains(child)) { - queue.add(child); - set.add(child); + Stack stack = new Stack<>(); + stack.push(kill); + Set tasksKilled = new HashSet<>(); + while (!stack.isEmpty()) { + int removedTask = stack.pop(); + tasksKilled.add(removedTask); + for (Integer childTask : map.getOrDefault(removedTask, new HashSet<>())) { + if (!tasksKilled.contains(childTask)) { + stack.push(childTask); } } } - return new ArrayList<>(set); + return new ArrayList<>(tasksKilled); } } diff --git a/Medium/Koko Eating Bananas.java b/Medium/Koko Eating Bananas.java index f0a7f6cb..821a21ca 100644 --- a/Medium/Koko Eating Bananas.java +++ b/Medium/Koko Eating Bananas.java @@ -1,33 +1,26 @@ class Solution { - public int minEatingSpeed(int[] piles, int H) { - int maxSize = piles[0]; + public int minEatingSpeed(int[] piles, int h) { + int start = 1; + int end = 0; for (int pile : piles) { - maxSize = Math.max(pile, maxSize); + end = Math.max(end, pile); } - return helper(piles, H, 1, maxSize); - } - - private int helper(int[] piles, int H, int start, int end) { - while (start < end) { - int mid = (start + end) / 2; - if (isPossible(piles, H, mid)) { - end = mid; - } - else { + while (start <= end) { + int mid = start + (end - start) / 2; + if (isPossible(piles, mid, h)) { + end = mid - 1; + } else { start = mid + 1; } } return start; } - private boolean isPossible(int[] piles, int H, int check) { + private boolean isPossible(int[] piles, int k, int h) { int numOfHours = 0; for (int pile : piles) { - int quot = pile / check; - numOfHours += quot == 0 ? 1 : quot; - numOfHours += quot > 0 && pile % check != 0 ? 1 : 0; + numOfHours += Math.ceil((double) pile / k); } - return numOfHours <= H; + return numOfHours <= h; } } - diff --git a/Medium/Kth Largest Element in an Array.java b/Medium/Kth Largest Element in an Array.java index 8c2a6d59..c45d1f68 100644 --- a/Medium/Kth Largest Element in an Array.java +++ b/Medium/Kth Largest Element in an Array.java @@ -1,18 +1,16 @@ class Solution { - public static int findKthLargest(int[] nums, int k) { - PriorityQueue queue = new PriorityQueue<>(k); - for (int i=0; i queue.peek()) { - queue.remove(); - queue.add(nums[i]); - } - } - } - - return queue.remove(); + public int findKthLargest(int[] nums, int k) { + int[] counter = new int[20001]; + for (int num : nums) { + counter[num + 10000]++; } + for (int i = counter.length - 1; i >= 0; i--) { + if (counter[i] < k) { + k -= counter[i]; + } else { + return i - 10000; + } + } + return -1; + } } diff --git a/Medium/Kth Largest Sum in a Binary Tree.java b/Medium/Kth Largest Sum in a Binary Tree.java new file mode 100644 index 00000000..01955179 --- /dev/null +++ b/Medium/Kth Largest Sum in a Binary Tree.java @@ -0,0 +1,41 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public long kthLargestLevelSum(TreeNode root, int k) { + PriorityQueue pq = new PriorityQueue<>(); + Queue queue = new LinkedList<>(); + queue.add(root); + while (!queue.isEmpty()) { + int size = queue.size(); + long sum = 0l; + while (size-- > 0) { + TreeNode removed = queue.remove(); + sum += removed.val; + if (removed.left != null) { + queue.add(removed.left); + } + if (removed.right != null) { + queue.add(removed.right); + } + } + pq.add(sum); + if (pq.size() > k) { + pq.poll(); + } + } + return pq.size() < k ? -1 : pq.poll(); + } +} diff --git a/Medium/Kth Smallest Element in a BST.java b/Medium/Kth Smallest Element in a BST.java index 74cb3112..6f77e133 100644 --- a/Medium/Kth Smallest Element in a BST.java +++ b/Medium/Kth Smallest Element in a BST.java @@ -15,17 +15,21 @@ */ class Solution { public int kthSmallest(TreeNode root, int k) { + Integer result = null; Stack stack = new Stack<>(); - while (true) { - while (root != null) { - stack.push(root); - root = root.left; - } - root = stack.pop(); - if (--k == 0) { - return root.val; + while (root != null) { + stack.push(root); + root = root.left; + } + while (k > 1 && !stack.isEmpty()) { + TreeNode removed = stack.pop(); + TreeNode rightNode = removed.right; + while (rightNode != null) { + stack.push(rightNode); + rightNode = rightNode.left; } - root = root.right; + k--; } + return stack.peek().val; } } diff --git a/Medium/Kth Smallest Element in a Sorted Matrix.java b/Medium/Kth Smallest Element in a Sorted Matrix.java index 37f81aec..37054ddf 100644 --- a/Medium/Kth Smallest Element in a Sorted Matrix.java +++ b/Medium/Kth Smallest Element in a Sorted Matrix.java @@ -1,37 +1,17 @@ class Solution { - public int kthSmallest(int[][] matrix, int k) { - PriorityQueue pq = new PriorityQueue<>(new Comparator() { - @Override - public int compare(Element o1, Element o2) { - return o1.val - o2.val; - } - }); - - for (int i=0; i pq = new PriorityQueue<>((o1, o2) -> o1[2] - o2[2]); + for (int j = 0; j < numOfRows; j++) { + pq.add(new int[]{0, j, matrix[0][j]}); } - - class Element { - int val; - int x; - int y; - - public Element(int val, int x, int y) { - this.val = val; - this.x = x; - this.y = y; - } + for (int i = 0; i < k - 1; i++) { + int[] removed = pq.poll(); + if (removed[0] == numOfRows - 1) { + continue; + } + pq.add(new int[]{removed[0] + 1, removed[1], matrix[removed[0] + 1][removed[1]]}); } + return pq.peek()[2]; + } } diff --git a/Medium/LRU Cache.java b/Medium/LRU Cache.java new file mode 100644 index 00000000..1e1b3ae6 --- /dev/null +++ b/Medium/LRU Cache.java @@ -0,0 +1,84 @@ +class LRUCache { + + private final Map map; + private final int capacity; + private final Node head; + private final Node tail; + + public LRUCache(int capacity) { + this.capacity = capacity; + this.map = new HashMap<>(); + this.head = new Node(-1, -1); + this.tail = new Node(-1, -1); + this.head.next = this.tail; + this.tail.prev = this.head; + } + + public int get(int key) { + if (!map.containsKey(key)) { + return -1; + } + Node node = map.get(key); + removeNode(node); + addToFront(node); + return node.value; + } + + public void put(int key, int value) { + if (map.containsKey(key)) { + updateExistingKey(key, value); + return; + } + if (map.size() == this.capacity) { + Node leastUsed = tail.prev; + removeNode(leastUsed); + map.remove(leastUsed.key); + } + Node newNode = new Node(key, value); + addToFront(newNode); + map.put(key, newNode); + } + + private void updateExistingKey(int key, int value) { + Node node = map.get(key); + Node updatedNode = new Node(key, value); + removeNode(node); + addToFront(updatedNode); + map.put(key, updatedNode); + } + + private void removeNode(Node node) { + Node prevToNode = node.prev; + Node nextToNode = node.next; + prevToNode.next = nextToNode; + nextToNode.prev = prevToNode; + } + + private void addToFront(Node node) { + Node nextToHead = head.next; + node.next = nextToHead; + nextToHead.prev = node; + node.prev = head; + head.next = node; + } + + private static class Node { + + private final int key; + private final int value; + private Node next; + private Node prev; + + public Node(int key, int value) { + this.key = key; + this.value = value; + } + } +} + +/** + * Your LRUCache object will be instantiated and called as such: + * LRUCache obj = new LRUCache(capacity); + * int param_1 = obj.get(key); + * obj.put(key,value); + */ diff --git a/Medium/Largest BST Subtree.java b/Medium/Largest BST Subtree.java index 45c83c6f..18ddfeaf 100644 --- a/Medium/Largest BST Subtree.java +++ b/Medium/Largest BST Subtree.java @@ -4,43 +4,41 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { public int largestBSTSubtree(TreeNode root) { - return largestBSTSubtreeHelper(root); - } - - private int largestBSTSubtreeHelper(TreeNode root) { - if (isBST(root)) { - return getNodeCount(root); - } - - return Math.max(-1, Math.max(largestBSTSubtreeHelper(root.left), largestBSTSubtreeHelper(root.right))); - } - - private boolean isBST(TreeNode root) { - return isBSTHelper(root, Integer.MAX_VALUE, Integer.MIN_VALUE); - } - - private boolean isBSTHelper(TreeNode root, int max, int min) { if (root == null) { - return true; + return 0; } - - if (root.val >= max || root.val <= min) { - return false; + int[] isBstResult = isBst(root, Integer.MIN_VALUE, Integer.MAX_VALUE); + if (isBstResult[0] == 1) { + return isBstResult[1]; } - - return isBSTHelper(root.left, root.val, min) && isBSTHelper(root.right, max, root.val); + return Math.max(largestBSTSubtree(root.left), largestBSTSubtree(root.right)); } - private int getNodeCount(TreeNode root) { + private int[] isBst(TreeNode root, int minValue, int maxValue) { if (root == null) { - return 0; + return new int[]{1, 0}; + } + int[] result = new int[2]; + if (!(root.val > minValue && root.val < maxValue)) { + return result; + } + int[] leftIsBst = isBst(root.left, minValue, root.val); + int[] rightIsBst = isBst(root.right, root.val, maxValue); + if (leftIsBst[0] == 1 && rightIsBst[0] == 1) { + result[0] = 1; + result[1] = 1 + leftIsBst[1] + rightIsBst[1]; } - - return 1 + getNodeCount(root.left) + getNodeCount(root.right); + return result; } } diff --git a/Medium/Largest Combination With Bitwise AND Greater Than Zero.java b/Medium/Largest Combination With Bitwise AND Greater Than Zero.java new file mode 100644 index 00000000..1399f1bb --- /dev/null +++ b/Medium/Largest Combination With Bitwise AND Greater Than Zero.java @@ -0,0 +1,17 @@ +class Solution { + public int largestCombination(int[] candidates) { + int[] bitCount = new int[24]; + for (int i = 0; i < 24; i++) { + for (int candidate : candidates) { + if ((candidate & (1 << i)) != 0) { + bitCount[i]++; + } + } + } + int result = 0; + for (int count : bitCount) { + result = Math.max(count, result); + } + return result; + } +} diff --git a/Medium/Largest Time for Given Digits.java b/Medium/Largest Time for Given Digits.java new file mode 100644 index 00000000..ca920ebb --- /dev/null +++ b/Medium/Largest Time for Given Digits.java @@ -0,0 +1,33 @@ +class Solution { + public String largestTimeFromDigits(int[] arr) { + int[] maxTime = {-1}; + permute(arr, 0, maxTime); + return maxTime[0] == -1 ? "" : String.format("%02d:%02d", maxTime[0] / 60, maxTime[0] % 60); + } + + private void permute(int[] arr, int idx, int[] maxTime) { + if (idx == arr.length) { + buildTime(arr, maxTime); + return; + } + for (int i = idx; i < arr.length; i++) { + swap(arr, i, idx); + permute(arr, idx + 1, maxTime); + swap(arr, idx, i); + } + } + + private void buildTime(int[] arr, int[] maxTime) { + int hour = arr[0] * 10 + arr[1]; + int minutes = arr[2] * 10 + arr[3]; + if (hour < 24 && minutes < 60) { + maxTime[0] = Math.max(maxTime[0], hour * 60 + minutes); + } + } + + private void swap(int[] arr, int i, int j) { + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } +} diff --git a/Medium/Last Moment Before All Ants Fall Out of a Plank.java b/Medium/Last Moment Before All Ants Fall Out of a Plank.java index 45e59801..e061b5d3 100644 --- a/Medium/Last Moment Before All Ants Fall Out of a Plank.java +++ b/Medium/Last Moment Before All Ants Fall Out of a Plank.java @@ -1,12 +1,12 @@ class Solution { - public int getLastMoment(int n, int[] left, int[] right) { - int res = 0; - for (int ant : left) { - res = Math.max(res, ant); + public int getLastMoment(int n, int[] left, int[] right) { + int result = 0; + for (int num : left) { + result = Math.max(result, num); + } + for (int num : right) { + result = Math.max(result, n - num); + } + return result; } - for (int ant : right) { - res = Math.max(res, n - ant); - } - return res; - } } diff --git a/Medium/Last Stone Weight II.java b/Medium/Last Stone Weight II.java index 73764b86..61c61dd6 100644 --- a/Medium/Last Stone Weight II.java +++ b/Medium/Last Stone Weight II.java @@ -1,19 +1,15 @@ class Solution { public int lastStoneWeightII(int[] stones) { - boolean[] dp = new boolean[1501]; - dp[0] = true; int sum = 0; for (int stone : stones) { sum += stone; - for (int i = Math.min(1500, sum); i >= stone; i--) { - dp[i] |= dp[i - stone]; - } } - for (int i = sum / 2; i >= 0; i--) { - if (dp[i]) { - return sum - i - i; + int[] dp = new int[sum / 2 + 1]; + for (int i = 1; i <= stones.length; i++) { + for (int j = sum / 2; j >= stones[i - 1]; j--) { + dp[j] = Math.max(dp[j], dp[j - stones[i - 1]] + stones[i - 1]); } } - return 0; + return sum - 2 * dp[sum / 2]; } } diff --git a/Medium/Least Number of Unique Integers after K Removals.java b/Medium/Least Number of Unique Integers after K Removals.java index 30b56fac..c6755d8e 100644 --- a/Medium/Least Number of Unique Integers after K Removals.java +++ b/Medium/Least Number of Unique Integers after K Removals.java @@ -1,28 +1,19 @@ class Solution { - public int findLeastNumOfUniqueInts(int[] arr, int k) { - Map map = new HashMap<>(); - List list = new ArrayList<>(); - for (int num : arr) { - if (!map.containsKey(num)) { - list.add(num); - } - map.put(num, map.getOrDefault(num, 0) + 1); + public int findLeastNumOfUniqueInts(int[] arr, int k) { + Map map = new HashMap<>(); + for (int num : arr) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + PriorityQueue pq = new PriorityQueue<>((a, b) -> map.get(a).compareTo(map.get(b))); + pq.addAll(map.keySet()); + while (k > 0 && !pq.isEmpty()) { + int count = map.get(pq.peek()); + if (count > k) { + break; + } + k -= count; + pq.poll(); + } + return pq.size(); } - Collections.sort(list, new Comparator(){ - public int compare(Integer o1, Integer o2) { - return map.get(o1) - map.get(o2); - } - }); - for (Integer num : list) { - int count = map.get(num); - k -= count; - if (k >= 0) { - map.remove(num); - } - else { - break; - } - } - return map.size(); - } } diff --git a/Medium/Leftmost Column with at Least a One.java b/Medium/Leftmost Column with at Least a One.java index 2cda1b1c..8b804b8f 100644 --- a/Medium/Leftmost Column with at Least a One.java +++ b/Medium/Leftmost Column with at Least a One.java @@ -2,38 +2,25 @@ * // This is the BinaryMatrix's API interface. * // You should not implement it, or speculate about its implementation * interface BinaryMatrix { - * public int get(int x, int y) {} + * public int get(int row, int col) {} * public List dimensions {} * }; */ class Solution { public int leftMostColumnWithOne(BinaryMatrix binaryMatrix) { - List dims = binaryMatrix.dimensions(); - int rows = dims.get(0); - int cols = dims.get(1); - int minIdx = Integer.MAX_VALUE; - for (int i = 0; i < rows; i++) { - int idx = binarySearch(binaryMatrix, i, 0, cols - 1); - if (idx != -1) { - minIdx = Math.min(minIdx, idx); + List dimension = binaryMatrix.dimensions(); + int numRows = dimension.get(0); + int numCols = dimension.get(1); + int currRow = 0; + int currCol = numCols - 1; + while (currRow < numRows && currCol >= 0) { + if (binaryMatrix.get(currRow, currCol) == 0) { + currRow++; + } else { + currCol--; } } - return minIdx == Integer.MAX_VALUE ? -1 : minIdx; - } - - private int binarySearch(BinaryMatrix binaryMatrix, int row, int start, int end) { - int minIdx = Integer.MAX_VALUE; - while (start <= end) { - int mid = (start + end) / 2; - if (binaryMatrix.get(row, mid) == 1) { - minIdx = Math.min(minIdx, mid); - end = mid - 1; - } - else { - start = mid + 1; - } - } - return minIdx == Integer.MAX_VALUE ? -1 : minIdx; + return currCol == numCols - 1 ? -1 : currCol + 1; } } diff --git a/Medium/Length of Longest Subarray With at Most K Frequency.java b/Medium/Length of Longest Subarray With at Most K Frequency.java new file mode 100644 index 00000000..82d8f62d --- /dev/null +++ b/Medium/Length of Longest Subarray With at Most K Frequency.java @@ -0,0 +1,19 @@ +class Solution { + public int maxSubarrayLength(int[] nums, int k) { + int start = 0; + int end = 0; + int result = 0; + int n = nums.length; + Map map = new HashMap<>(); + while (end < n) { + map.put(nums[end], map.getOrDefault(nums[end], 0) + 1); + while (start < end && map.get(nums[end]) > k) { + map.put(nums[start], map.get(nums[start]) - 1); + start++; + } + end++; + result = Math.max(result, end - start); + } + return result; + } +} diff --git a/Medium/Length of the Longest Alphabetical Continuous Substring.java b/Medium/Length of the Longest Alphabetical Continuous Substring.java new file mode 100644 index 00000000..30426403 --- /dev/null +++ b/Medium/Length of the Longest Alphabetical Continuous Substring.java @@ -0,0 +1,14 @@ +class Solution { + public int longestContinuousSubstring(String s) { + int idx = 0; + int maxLength = 0; + while (idx < s.length()) { + int currIdx = idx++; + while (idx < s.length() && s.charAt(idx) - s.charAt(idx - 1) == 1) { + idx++; + } + maxLength = Math.max(maxLength, idx - currIdx); + } + return maxLength; + } +} diff --git a/Medium/Letter Combinations of a Phone Number.java b/Medium/Letter Combinations of a Phone Number.java index 81be5ec2..b145954b 100644 --- a/Medium/Letter Combinations of a Phone Number.java +++ b/Medium/Letter Combinations of a Phone Number.java @@ -1,35 +1,32 @@ class Solution { - public List letterCombinations(String digits) { - if (digits.length() == 0) { - return new ArrayList<>(); + private static final Map DIGIT_TO_CHAR_MAPPING = Map.of( + '2', "abc", + '3', "def", + '4', "ghi", + '5', "jkl", + '6', "mno", + '7', "pqrs", + '8', "tuv", + '9', "wxyz" + ); + + public List letterCombinations(String digits) { + List result = new ArrayList<>(); + letterCombinations(digits, 0, new StringBuilder(), result); + return result; } - String[] strs = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; - Map map = new HashMap<>(); - for (int i = 2; i <= 9; i++) { - map.put(i, strs[i - 2]); - } - List list = new ArrayList<>(); - helper(digits, 0, digits.length(), new StringBuilder(), map, list); - return list; - } - - private void helper( - String digits, int idx, int n, StringBuilder sb, Map map, List list - ) { - if (idx == n) { - if (sb.length() == n) { - list.add(sb.toString()); - } - } - else { - for (int i = idx; i < n; i++) { - int digit = Character.getNumericValue(digits.charAt(i)); - for (char c : map.get(digit).toCharArray()) { - sb.append(c); - helper(digits, i + 1, n, sb, map, list); - sb.deleteCharAt(sb.length() - 1); + + private void letterCombinations(String digits, int idx, StringBuilder sb, List result) { + if (idx == digits.length()) { + if (!sb.isEmpty()) { + result.add(sb.toString()); + } + return; + } + for (char c : DIGIT_TO_CHAR_MAPPING.get(digits.charAt(idx)).toCharArray()) { + sb.append(c); + letterCombinations(digits, idx + 1, sb, result); + sb.deleteCharAt(sb.length() - 1); } - } } - } } diff --git a/Medium/Lexicographical Numbers.java b/Medium/Lexicographical Numbers.java new file mode 100644 index 00000000..4476017b --- /dev/null +++ b/Medium/Lexicographical Numbers.java @@ -0,0 +1,18 @@ +class Solution { + public List lexicalOrder(int n) { + List result = new ArrayList<>(); + int curr = 1; + for (int i = 0; i < n; i++) { + result.add(curr); + if (curr * 10 <= n) { + curr *= 10; + } else { + while (curr % 10 == 9 || curr == n) { + curr /= 10; + } + curr++; + } + } + return result; + } +} diff --git a/Medium/Lexicographically Minimum String After Removing Stars.java b/Medium/Lexicographically Minimum String After Removing Stars.java new file mode 100644 index 00000000..794ee712 --- /dev/null +++ b/Medium/Lexicographically Minimum String After Removing Stars.java @@ -0,0 +1,28 @@ +class Solution { + public String clearStars(String s) { + Deque[] count = new Deque[26]; + for (int i = 0; i < 26; i++) { + count[i] = new ArrayDeque<>(); + } + char[] letters = s.toCharArray(); + for (int i = 0; i < letters.length; i++) { + if (letters[i] != '*') { + count[letters[i] - 'a'].push(i); + } else { + for (int j = 0; j < 26; j++) { + if (!count[j].isEmpty()) { + letters[count[j].pop()] = '*'; + break; + } + } + } + } + StringBuilder sb = new StringBuilder(); + for (char c : letters) { + if (c != '*') { + sb.append(c); + } + } + return sb.toString(); + } +} diff --git a/Medium/Lexicographically Smallest Equivalent String.java b/Medium/Lexicographically Smallest Equivalent String.java new file mode 100644 index 00000000..f4d01c21 --- /dev/null +++ b/Medium/Lexicographically Smallest Equivalent String.java @@ -0,0 +1,46 @@ +class Solution { + public String smallestEquivalentString(String s1, String s2, String baseStr) { + UnionFind unionFind = new UnionFind(26); + for (int i = 0; i < s1.length(); i++) { + char c1 = s1.charAt(i); + char c2 = s2.charAt(i); + unionFind.union(c1 - 'a', c2 - 'a'); + } + StringBuilder result = new StringBuilder(); + for (char c : baseStr.toCharArray()) { + result.append((char) (unionFind.find(c - 'a') + 'a')); + } + return result.toString(); + } + + class UnionFind { + private int[] parent; + + public UnionFind(int n) { + parent = new int[n]; + for (int i = 0; i < n; i++) { + parent[i] = i; + } + } + + public int find(int node) { + if (parent[node] == node) { + return node; + } + parent[node] = find(parent[node]); + return parent[node]; + } + + public void union(int nodeOne, int nodeTwo) { + int parentOne = find(nodeOne); + int parentTwo = find(nodeTwo); + if (parentOne != parentTwo) { + if (parentOne < parentTwo) { + parent[parentTwo] = parentOne; + } else { + parent[parentOne] = parentTwo; + } + } + } + } +} diff --git a/Medium/Lexicographically Smallest String After Substring Operation.java b/Medium/Lexicographically Smallest String After Substring Operation.java new file mode 100644 index 00000000..e55990b7 --- /dev/null +++ b/Medium/Lexicographically Smallest String After Substring Operation.java @@ -0,0 +1,20 @@ +class Solution { + public String smallestString(String s) { + StringBuilder sb = new StringBuilder(); + int idx = 0; + while (idx < s.length() && s.charAt(idx) == 'a') { + sb.append(s.charAt(idx++)); + } + if (idx == s.length()) { + return s.substring(0, s.length() - 1) + 'z'; + } + while (idx < s.length() && s.charAt(idx) != 'a') { + sb.append(getPreviousChar(s.charAt(idx++))); + } + return sb.append(s.substring(idx)).toString(); + } + + private char getPreviousChar(char c) { + return (char) (c - 1); + } +} diff --git a/Medium/Linked List Components.java b/Medium/Linked List Components.java index 1d32410d..62322281 100644 --- a/Medium/Linked List Components.java +++ b/Medium/Linked List Components.java @@ -3,30 +3,26 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { - public int numComponents(ListNode head, int[] G) { - int count = 0; - Set set = new HashSet<>(); - for (int g : G) { - set.add(g); + public int numComponents(ListNode head, int[] G) { + int numOfComponents = 0; + Set set = Arrays.stream(G).boxed().collect(Collectors.toSet()); + while (head != null && !set.isEmpty()) { + if (set.contains(head.val)) { + while (head != null && !set.isEmpty() && set.contains(head.val)) { + set.remove(head.val); + head = head.next; } - - while (head != null) { - if (set.contains(head.val)) { - while (head != null && set.contains(head.val)) { - head = head.next; - } - - count++; - } - else { - head = head.next; - } - } - - return count; + numOfComponents++; + } else { + head = head.next; + } } + return numOfComponents; + } } diff --git a/Medium/Linked List Cycle II.java b/Medium/Linked List Cycle II.java index ba59422b..2a88b1b4 100644 --- a/Medium/Linked List Cycle II.java +++ b/Medium/Linked List Cycle II.java @@ -10,26 +10,24 @@ * } */ public class Solution { - public ListNode detectCycle(ListNode head) { - ListNode slow = head; - ListNode fast = head; - boolean cycle = false; - while (fast != null && fast.next != null) { - slow = slow.next; - fast = fast.next.next; - if (slow == fast) { - cycle = true; - break; - } + public ListNode detectCycle(ListNode head) { + ListNode slow = head; + ListNode fast = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + if (slow == fast) { + break; + } + } + if (fast == null || fast.next == null) { + return null; + } + ListNode curr = head; + while (curr != slow) { + curr = curr.next; + slow = slow.next; + } + return curr; } - if (!cycle) { - return null; - } - slow = head; - while (slow != fast) { - slow = slow.next; - fast = fast.next; - } - return slow; - } } diff --git a/Medium/Linked List Frequency.java b/Medium/Linked List Frequency.java new file mode 100644 index 00000000..1c5a1739 --- /dev/null +++ b/Medium/Linked List Frequency.java @@ -0,0 +1,25 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode frequenciesOfElements(ListNode head) { + Map map = new HashMap<>(); + for (ListNode curr = head; curr != null; curr = curr.next) { + map.put(curr.val, map.getOrDefault(curr.val, 0) + 1); + } + ListNode dummy = new ListNode(-1); + ListNode curr = dummy; + for (Integer key : map.keySet()) { + curr.next = new ListNode(map.get(key)); + curr = curr.next; + } + return dummy.next; + } +} diff --git a/Medium/Linked List in Binary Tree.java b/Medium/Linked List in Binary Tree.java index 065a25c3..9ba90a87 100644 --- a/Medium/Linked List in Binary Tree.java +++ b/Medium/Linked List in Binary Tree.java @@ -3,7 +3,9 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ /** @@ -12,31 +14,33 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { public boolean isSubPath(ListNode head, TreeNode root) { + if (head == null) { + return true; + } if (root == null) { return false; } - return ( - helper(head, root) || - isSubPath(head, root.left) || - isSubPath(head, root.right) - ); - } + return dfs(head, root) || isSubPath(head, root.left) || isSubPath(head, root.right); + } - private boolean helper(ListNode head, TreeNode root) { + private boolean dfs(ListNode head, TreeNode root) { if (head == null) { return true; } - if (head != null && root == null) { - return false; - } - if (head.val != root.val) { + if (root == null) { return false; } - return helper(head.next, root.left) || helper(head.next, root.right); + return head.val == root.val && (dfs(head.next, root.left) || dfs(head.next, root.right)); } } diff --git a/Medium/Lonely Pixel I.java b/Medium/Lonely Pixel I.java index ae676662..42ae180d 100644 --- a/Medium/Lonely Pixel I.java +++ b/Medium/Lonely Pixel I.java @@ -1,37 +1,25 @@ class Solution { - public int findLonelyPixel(char[][] picture) { - int count = 0; - Map rowMap = new HashMap<>(); - - for (int i=0; i rowMap = new HashMap<>(); + Map colMap = new HashMap<>(); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (picture[i][j] == 'B') { + rowMap.put(i, rowMap.getOrDefault(i, 0) + 1); + colMap.put(j, colMap.getOrDefault(j, 0) + 1); } - - Map colMap = new HashMap<>(); - for (int i=0; i map = new HashMap<>(); + int maxValue = 0; + for (int num : arr) { + int endingSubLength = map.getOrDefault(num - difference, 0); + map.put(num, endingSubLength + 1); + maxValue = Math.max(maxValue, map.get(num)); + } + return maxValue; + } +} diff --git a/Medium/Longest Arithmetic Subsequence.java b/Medium/Longest Arithmetic Subsequence.java new file mode 100644 index 00000000..67a7fbb6 --- /dev/null +++ b/Medium/Longest Arithmetic Subsequence.java @@ -0,0 +1,15 @@ +class Solution { + public int longestArithSeqLength(int[] nums) { + int result = 0; + Map[] dp = new HashMap[nums.length]; + for (int i = 0; i < nums.length; i++) { + dp[i] = new HashMap<>(); + for (int j = 0; j < i; j++) { + int diff = nums[j] - nums[i]; + dp[i].put(diff, dp[j].getOrDefault(diff, 1) + 1); + result = Math.max(result, dp[i].get(diff)); + } + } + return result; + } +} diff --git a/Medium/Longest Common Subsequence Between Sorted Arrays.java b/Medium/Longest Common Subsequence Between Sorted Arrays.java new file mode 100644 index 00000000..d050d3fd --- /dev/null +++ b/Medium/Longest Common Subsequence Between Sorted Arrays.java @@ -0,0 +1,15 @@ +class Solution { + public List longestCommonSubsequence(int[][] arrays) { + List result = new ArrayList<>(); + Map map = new HashMap<>(); + for (int[] arr : arrays) { + for (int num : arr) { + map.put(num, map.getOrDefault(num, 0) + 1); + if (map.get(num) == arrays.length) { + result.add(num); + } + } + } + return result; + } +} diff --git a/Medium/Longest Common Subsequence.java b/Medium/Longest Common Subsequence.java new file mode 100644 index 00000000..43fc5464 --- /dev/null +++ b/Medium/Longest Common Subsequence.java @@ -0,0 +1,17 @@ +class Solution { + public int longestCommonSubsequence(String text1, String text2) { + int n = text1.length(); + int m = text2.length(); + int[][] dp = new int[n + 1][m + 1]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (text1.charAt(i) == text2.charAt(j)) { + dp[i + 1][j + 1] = 1 + dp[i][j]; + } else { + dp[i + 1][j + 1] = Math.max(dp[i + 1][j], dp[i][j + 1]); + } + } + } + return dp[n][m]; + } +} diff --git a/Medium/Longest Consecutive Sequence.java b/Medium/Longest Consecutive Sequence.java new file mode 100644 index 00000000..e977e86a --- /dev/null +++ b/Medium/Longest Consecutive Sequence.java @@ -0,0 +1,21 @@ +class Solution { + public int longestConsecutive(int[] nums) { + Set set = new HashSet<>(); + for (int num : nums) { + set.add(num); + } + int maxLength = 0; + for (int num : set) { + if (!set.contains(num - 1)) { + int currNum = num; + int currentLength = 1; + while (set.contains(currNum + 1)) { + currNum++; + currentLength++; + } + maxLength = Math.max(currentLength, maxLength); + } + } + return maxLength; + } +} diff --git a/Medium/Longest Happy String.java b/Medium/Longest Happy String.java new file mode 100644 index 00000000..4af8f747 --- /dev/null +++ b/Medium/Longest Happy String.java @@ -0,0 +1,42 @@ +class Solution { + public String longestDiverseString(int a, int b, int c) { + PriorityQueue pq = + new PriorityQueue<>((p, q) -> q.frequency() - p.frequency()); + if (a > 0) { + pq.add(new LetterFrequencyPair('a', a)); + } + if (b > 0) { + pq.add(new LetterFrequencyPair('b', b)); + } + if (c > 0) { + pq.add(new LetterFrequencyPair('c', c)); + } + StringBuilder sb = new StringBuilder(); + while (!pq.isEmpty()) { + LetterFrequencyPair removed = pq.remove(); + int frequency = removed.frequency(); + int resultLength = sb.length(); + if (resultLength >= 2 && + sb.charAt(resultLength - 1) == removed.letter() && + sb.charAt(resultLength - 2) == removed.letter()) { + if (pq.isEmpty()) { + break; + } + LetterFrequencyPair temp = pq.remove(); + sb.append(temp.letter()); + if (temp.frequency() - 1 > 0) { + pq.add(new LetterFrequencyPair(temp.letter(), temp.frequency() - 1)); + } + } else { + sb.append(removed.letter()); + frequency--; + } + if (frequency > 0) { + pq.add(new LetterFrequencyPair(removed.letter(), frequency)); + } + } + return sb.toString(); + } + + private record LetterFrequencyPair(char letter, int frequency) {} +} diff --git a/Medium/Longest Increasing Subsequence.java b/Medium/Longest Increasing Subsequence.java index fd5f299e..b56c14ef 100644 --- a/Medium/Longest Increasing Subsequence.java +++ b/Medium/Longest Increasing Subsequence.java @@ -1,21 +1,18 @@ class Solution { public int lengthOfLIS(int[] nums) { - int[] dp = new int[nums.length]; - Arrays.fill(dp, 1); - - for (int i = 1; i < nums.length; i ++) { - for (int j = 0; j < i; j++) { - if (nums[j] < nums[i]) { - dp[i] = Math.max(dp[i], dp[j] + 1); + List subsequence = new ArrayList<>(); + subsequence.add(nums[0]); + for (int i = 1; i < nums.length; i++) { + if (nums[i] > subsequence.get(subsequence.size() - 1)) { + subsequence.add(nums[i]); + } else { + int idx = 0; + while (nums[i] > subsequence.get(idx)) { + idx++; } + subsequence.set(idx, nums[i]); } } - - int max = Integer.MIN_VALUE; - for (int num : dp) { - max = Math.max(num, max); - } - - return max == Integer.MIN_VALUE ? 0 : max; + return subsequence.size(); } } diff --git a/Medium/Longest Palindromic Subsequence.java b/Medium/Longest Palindromic Subsequence.java index 5d9d4dfd..85c6c5e7 100644 --- a/Medium/Longest Palindromic Subsequence.java +++ b/Medium/Longest Palindromic Subsequence.java @@ -1,34 +1,25 @@ class Solution { public int longestPalindromeSubseq(String s) { - int[][] temp = new int[s.length()][s.length()]; - for(int i=0;i endIdx) { + return 0; } - - int j; - - for (int cl=2;cl <= s.length();cl++) { - for (int i=0;i uniqueNums = new HashSet<>(); + for (int num : nums) { + uniqueNums.add(num); + } + int result = 0; + for (int num : nums) { + int currStreak = 0; + long curr = num; + while (uniqueNums.contains((int) curr)) { + currStreak++; + if (curr * curr > LIMIT) { + break; + } + curr *= curr; + } + result = Math.max(result, currStreak); + } + return result < 2 ? -1 : result; + } +} diff --git a/Medium/Longest String Chain.java b/Medium/Longest String Chain.java new file mode 100644 index 00000000..5c36ef9d --- /dev/null +++ b/Medium/Longest String Chain.java @@ -0,0 +1,31 @@ +class Solution { + public int longestStrChain(String[] words) { + Set wordSet = Arrays.stream(words) + .collect(Collectors.toSet()); + Map memo = new HashMap<>(); + int result = 0; + for (String word : words) { + result = Math.max(result, dfs(wordSet, memo, word)); + } + return result; + } + + private int dfs(Set wordSet, Map memo, String word) { + if (memo.containsKey(word)) { + return memo.get(word); + } + int maxLength = 1; + StringBuilder sb = new StringBuilder(word); + for (int i = 0; i < word.length(); i++) { + sb.deleteCharAt(i); + String newWord = sb.toString(); + if (wordSet.contains(newWord)) { + int currLength = 1 + dfs(wordSet, memo, newWord); + maxLength = Math.max(maxLength, currLength); + } + sb.insert(i, word.charAt(i)); + } + memo.put(word, maxLength); + return maxLength; + } +} diff --git a/Medium/Longest Subarray With Maximum Bitwise AND.java b/Medium/Longest Subarray With Maximum Bitwise AND.java new file mode 100644 index 00000000..63c1ca55 --- /dev/null +++ b/Medium/Longest Subarray With Maximum Bitwise AND.java @@ -0,0 +1,20 @@ +class Solution { + public int longestSubarray(int[] nums) { + int result = 0; + int max = 0; + int count = 0; + for (int num : nums) { + if (max < num) { + max = num; + result = count = 0; + } + if (max == num) { + count++; + } else { + count = 0; + } + result = Math.max(result, count); + } + return result; + } +} diff --git a/Medium/Longest Subarray of 1's After Deleting One Element.java b/Medium/Longest Subarray of 1's After Deleting One Element.java new file mode 100644 index 00000000..b10a1675 --- /dev/null +++ b/Medium/Longest Subarray of 1's After Deleting One Element.java @@ -0,0 +1,15 @@ +class Solution { + public int longestSubarray(int[] nums) { + int zeroIdx = -1; + int windowSize = 0; + int startIdx = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] == 0) { + startIdx = zeroIdx + 1; + zeroIdx = i; + } + windowSize = Math.max(windowSize, i - startIdx); + } + return windowSize; + } +} diff --git a/Medium/Longest Substring Without Repeating Characters.java b/Medium/Longest Substring Without Repeating Characters.java index 47cd512b..2bef7542 100644 --- a/Medium/Longest Substring Without Repeating Characters.java +++ b/Medium/Longest Substring Without Repeating Characters.java @@ -1,21 +1,18 @@ class Solution { - public int lengthOfLongestSubstring(String s) { - int maxLen = 0; - int n = s.length(); - int start = 0; - int end = 0; - Set set = new HashSet<>(); - - while (end < n) { - if (!set.contains(s.charAt(end))) { - set.add(s.charAt(end++)); - maxLen = Math.max(maxLen, set.size()); - } - else { - set.remove(s.charAt(start++)); - } - } - - return maxLen; + public int lengthOfLongestSubstring(String s) { + int start = 0; + int end = 0; + int n = s.length(); + Map map = new HashMap<>(); + int maxLength = 0; + while (end < n) { + char c = s.charAt(end++); + map.put(c, map.getOrDefault(c, 0) + 1); + while (start <= end && map.get(c) > 1) { + map.put(s.charAt(start), map.getOrDefault(s.charAt(start++), 0) - 1); + } + maxLength = Math.max(maxLength, end - start); } + return maxLength; + } } diff --git a/Medium/Longest Substring with At Most K Distinct Characters.java b/Medium/Longest Substring with At Most K Distinct Characters.java new file mode 100644 index 00000000..a793b8c0 --- /dev/null +++ b/Medium/Longest Substring with At Most K Distinct Characters.java @@ -0,0 +1,21 @@ +class Solution { + public int lengthOfLongestSubstringKDistinct(String s, int k) { + Map map = new HashMap<>(); + int start = 0; + int end = 0; + int maxLength = 0; + while (end < s.length()) { + map.put(s.charAt(end), map.getOrDefault(s.charAt(end), 0) + 1); + while (start <= end && map.size() > k) { + map.put(s.charAt(start), map.get(s.charAt(start)) - 1); + if (map.get(s.charAt(start)) == 0) { + map.remove(s.charAt(start)); + } + start++; + } + end++; + maxLength = Math.max(maxLength, end - start); + } + return maxLength; + } +} diff --git a/Medium/Longest Substring with At Most Two Distinct Characters.java b/Medium/Longest Substring with At Most Two Distinct Characters.java new file mode 100644 index 00000000..04f60a83 --- /dev/null +++ b/Medium/Longest Substring with At Most Two Distinct Characters.java @@ -0,0 +1,22 @@ +class Solution { + public int lengthOfLongestSubstringTwoDistinct(String s) { + int max = 0; + int start = 0; + int end = 0; + int n = s.length(); + Map map = new HashMap<>(); + while (end < n) { + map.put(s.charAt(end), map.getOrDefault(s.charAt(end), 0) + 1); + end++; + while (start < end && map.size() > 2) { + map.put(s.charAt(start), map.getOrDefault(s.charAt(start), 0) - 1); + if (map.get(s.charAt(start)) == 0) { + map.remove(s.charAt(start)); + } + start++; + } + max = Math.max(max, end - start); + } + return max; + } +} diff --git a/Medium/Longest Uploaded Prefix.java b/Medium/Longest Uploaded Prefix.java new file mode 100644 index 00000000..f7d3f6f1 --- /dev/null +++ b/Medium/Longest Uploaded Prefix.java @@ -0,0 +1,28 @@ +class LUPrefix { + + private int longestPrefixIndex; + private boolean[] uploaded; + + public LUPrefix(int n) { + this.uploaded = new boolean[n]; + this.longestPrefixIndex = 0; + } + + public void upload(int video) { + uploaded[video - 1] = true; + while (longestPrefixIndex < uploaded.length && uploaded[longestPrefixIndex]) { + longestPrefixIndex++; + } + } + + public int longest() { + return longestPrefixIndex; + } +} + +/** + * Your LUPrefix object will be instantiated and called as such: + * LUPrefix obj = new LUPrefix(n); + * obj.upload(video); + * int param_2 = obj.longest(); + */ diff --git a/Medium/Longest Word With All Prefixes.java b/Medium/Longest Word With All Prefixes.java new file mode 100644 index 00000000..a2a69a0f --- /dev/null +++ b/Medium/Longest Word With All Prefixes.java @@ -0,0 +1,59 @@ +class Solution { + public String longestWord(String[] words) { + TrieNode root = new TrieNode(); + for (String word : words) { + root.insert(word); + } + String longestValidWord = ""; + for (String word : words) { + if (root.hasAllPrefixes(word)) { + if (word.length() > longestValidWord.length() || + (word.length() == longestValidWord.length() && word.compareTo(longestValidWord) < 0)) { + longestValidWord = word; + } + } + } + return longestValidWord; + } + + static class TrieNode { + private final Map children; + private boolean isWord; + + public TrieNode() { + this.children = new HashMap<>(); + } + + public void insert(String word) { + TrieNode curr = this; + for (char c : word.toCharArray()) { + curr = curr.getOrCreateChild(c); + } + curr.isWord = true; + } + + public boolean hasAllPrefixes(String word) { + TrieNode curr = this; + for (char c : word.toCharArray()) { + TrieNode child = curr.children.getOrDefault(c, null); + if (child == null) { + return false; + } + if (!child.isWord) { + return false; + } + curr = child; + } + return true; + } + + private TrieNode getOrCreateChild(char c) { + if (children.containsKey(c)) { + return children.get(c); + } + TrieNode node = new TrieNode(); + children.put(c, node); + return node; + } + } +} diff --git a/Medium/Longest Word in Dictionary through Deleting.java b/Medium/Longest Word in Dictionary through Deleting.java new file mode 100644 index 00000000..5f09bd58 --- /dev/null +++ b/Medium/Longest Word in Dictionary through Deleting.java @@ -0,0 +1,20 @@ +class Solution { + public String findLongestWord(String s, List d) { + d.sort((o1, o2) -> o1.length() != o2.length() ? Integer.compare(o2.length(), o1.length()) + : o1.compareTo(o2)); + for (String word : d) { + int wordIdx = 0; + int strIdx = 0; + while (strIdx < s.length() && wordIdx < word.length()) { + if (word.charAt(wordIdx) == s.charAt(strIdx)) { + wordIdx++; + } + strIdx++; + } + if (wordIdx == word.length()) { + return word; + } + } + return ""; + } +} diff --git a/Medium/Longest ZigZag Path in a Binary Tree.java b/Medium/Longest ZigZag Path in a Binary Tree.java index bdc3e8f9..71e32231 100644 --- a/Medium/Longest ZigZag Path in a Binary Tree.java +++ b/Medium/Longest ZigZag Path in a Binary Tree.java @@ -4,33 +4,39 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - int max; - public int longestZigZag(TreeNode root) { - if (root == null) { - return -1; + + private enum DIRECTION { + LEFT, RIGHT; } - max = 0; - helper(root.right, 1, true); - helper(root.left, 1, false); - return max; - } - - private void helper(TreeNode root, int step, boolean isRight) { - if (root == null) { - return; + + public int longestZigZag(TreeNode root) { + int[] pathLength = {0}; + dfs(root, DIRECTION.LEFT, 0, pathLength); + dfs(root, DIRECTION.RIGHT, 0, pathLength); + return pathLength[0]; } - max = Math.max(max, step); - if (isRight) { - helper(root.left, step + 1, false); - helper(root.right, 1, true); + + private void dfs(TreeNode node, DIRECTION direction, int steps, int[] pathLength) { + if (node == null) { + return; + } + pathLength[0] = Math.max(pathLength[0], steps); + if (direction == DIRECTION.LEFT) { + dfs(node.left, DIRECTION.RIGHT, steps + 1, pathLength); + dfs(node.right, DIRECTION.LEFT, 1, pathLength); + } else { + dfs(node.left, DIRECTION.RIGHT, 1, pathLength); + dfs(node.right, DIRECTION.LEFT, steps + 1, pathLength); + } } - else { - helper(root.right, step + 1, true); - helper(root.left, 1, false); - } - } } diff --git a/Medium/Lowest Common Ancestor of Deepest Leaves.java b/Medium/Lowest Common Ancestor of Deepest Leaves.java index 4517a201..d1fdfc59 100644 --- a/Medium/Lowest Common Ancestor of Deepest Leaves.java +++ b/Medium/Lowest Common Ancestor of Deepest Leaves.java @@ -4,40 +4,42 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ -class Solution { - public TreeNode lcaDeepestLeaves(TreeNode root) { - return helper(root).lowesetCommonAncestor; +class Solution { + public TreeNode lcaDeepestLeaves(TreeNode root) { + return dfs(root).node; + } + + private NodeResult dfs(TreeNode root) { + if (root == null) { + return new NodeResult(null, 0); } - - private UpdatedTreeNode helper(TreeNode root) { - if (root == null) { - return new UpdatedTreeNode(0, null); - } - - UpdatedTreeNode leftUpdated = helper(root.left); - UpdatedTreeNode rightUpdated = helper(root.right); - - if (leftUpdated.depth == rightUpdated.depth) { - return new UpdatedTreeNode(leftUpdated.depth + 1, root); - } - else if (leftUpdated.depth > rightUpdated.depth) { - return new UpdatedTreeNode(leftUpdated.depth + 1, leftUpdated.lowesetCommonAncestor); - } - else { - return new UpdatedTreeNode(rightUpdated.depth + 1, rightUpdated.lowesetCommonAncestor); - } + NodeResult leftResult = dfs(root.left); + NodeResult rightResult = dfs(root.right); + if (leftResult.distance > rightResult.distance) { + return new NodeResult(leftResult.node, leftResult.distance + 1); } -} - -class UpdatedTreeNode { - public int depth; - public TreeNode lowesetCommonAncestor; - - public UpdatedTreeNode(int depth, TreeNode node) { - this.depth = depth; - this.lowesetCommonAncestor = node; + if (leftResult.distance < rightResult.distance) { + return new NodeResult(rightResult.node, rightResult.distance + 1); + } + return new NodeResult(root, rightResult.distance + 1); + } + + private static class NodeResult { + TreeNode node; + int distance; + + public NodeResult(TreeNode node, int distance) { + this.node = node; + this.distance = distance; } + } } diff --git a/Medium/Lowest Common Ancestor of a Binary Tree II.java b/Medium/Lowest Common Ancestor of a Binary Tree II.java new file mode 100644 index 00000000..be4c28d2 --- /dev/null +++ b/Medium/Lowest Common Ancestor of a Binary Tree II.java @@ -0,0 +1,46 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +class Solution { + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + TreeNode result = lca(root, p, q); + if (result == p) { + return checkIfNodeExist(p, q) ? p : null; + } + if (result == q) { + return checkIfNodeExist(q, p) ? q : null; + } + return result; + } + + private boolean checkIfNodeExist(TreeNode root, TreeNode target) { + if (root == target) { + return true; + } + if (root == null) { + return false; + } + return checkIfNodeExist(root.left, target) || checkIfNodeExist(root.right, target); + } + + private TreeNode lca(TreeNode root, TreeNode p, TreeNode q) { + if (root == null) { + return root; + } + if (root == p || root == q) { + return root; + } + TreeNode left = lca(root.left, p, q); + TreeNode right = lca(root.right, p, q); + if (left != null && right != null) { + return root; + } + return left != null ? left : right; + } +} diff --git a/Medium/Lowest Common Ancestor of a Binary Tree III.java b/Medium/Lowest Common Ancestor of a Binary Tree III.java new file mode 100644 index 00000000..098b0f86 --- /dev/null +++ b/Medium/Lowest Common Ancestor of a Binary Tree III.java @@ -0,0 +1,38 @@ +/* +// Definition for a Node. +class Node { + public int val; + public Node left; + public Node right; + public Node parent; +}; +*/ + +class Solution { + public Node lowestCommonAncestor(Node p, Node q) { + int pDepth = getDepth(p); + int qDepth = getDepth(q); + while (pDepth > qDepth) { + pDepth--; + p = p.parent; + } + while (qDepth > pDepth) { + qDepth--; + q = q.parent; + } + while (p != q) { + p = p.parent; + q = q.parent; + } + return p; + } + + private int getDepth(Node node) { + int depth = 0; + while (node != null) { + depth++; + node = node.parent; + } + return depth; + } +} diff --git a/Medium/Lowest Common Ancestor of a Binary Tree.java b/Medium/Lowest Common Ancestor of a Binary Tree.java index b83d0663..890c71e6 100644 --- a/Medium/Lowest Common Ancestor of a Binary Tree.java +++ b/Medium/Lowest Common Ancestor of a Binary Tree.java @@ -9,17 +9,20 @@ */ class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { - if (root == null || root == p || root == q) { + if (root == null) { + return null; + } + if (root == p || root == q) { return root; } - TreeNode left = lowestCommonAncestor(root.left, p, q); TreeNode right = lowestCommonAncestor(root.right, p, q); - if (left != null && right != null) { return root; } - - return left != null ? left : right; + if (left != null || right != null) { + return left != null ? left : right; + } + return null; } } diff --git a/Medium/Magnetic Force Between Two Balls.java b/Medium/Magnetic Force Between Two Balls.java new file mode 100644 index 00000000..9ca9708b --- /dev/null +++ b/Medium/Magnetic Force Between Two Balls.java @@ -0,0 +1,32 @@ +class Solution { + public int maxDistance(int[] position, int m) { + int result = 0; + int n = position.length; + Arrays.sort(position); + int left = 1; + int right = (int) Math.ceil(position[n - 1] / (m - 1.0)); + while (left <= right) { + int mid = (left + right) / 2; + if (isPossible(position, mid, m)) { + result = mid; + left = mid + 1; + } else { + right = mid - 1; + } + } + return result; + } + + private boolean isPossible(int[] position, int distance, int m) { + int prevBall = position[0]; + int ballCount = 1; + for (int i = 1; i < position.length && ballCount < m; i++) { + int curr = position[i]; + if (curr - prevBall >= distance) { + ballCount++; + prevBall = curr; + } + } + return ballCount == m; + } +} diff --git a/Medium/Majority Element II.java b/Medium/Majority Element II.java index 4d55d74e..5b59752e 100644 --- a/Medium/Majority Element II.java +++ b/Medium/Majority Element II.java @@ -1,46 +1,43 @@ class Solution { - public List majorityElement(int[] nums) { - int countOne = 0; - int countTwo = 0; - Integer candidateOne = null; - Integer candidateTwo = null; - for (int num : nums) { - if (candidateOne != null && candidateOne == num) { - countOne++; - } - else if (candidateTwo != null && candidateTwo == num) { - countTwo++; - } - else if (countOne == 0) { - candidateOne = num; - countOne = 1; - } - else if (countTwo == 0) { - candidateTwo = num; - countTwo = 1; - } - else { - countOne--; - countTwo--; - } + public List majorityElement(int[] nums) { + Integer candidateOne = null; + Integer candidateTwo = null; + int countOne = 0; + int countTwo = 0; + for (int num : nums) { + if (candidateOne != null && candidateOne == num) { + countOne++; + } else if (candidateTwo != null && candidateTwo == num) { + countTwo++; + } else if (countOne == 0) { + candidateOne = num; + countOne++; + } else if (countTwo == 0) { + candidateTwo = num; + countTwo++; + } else { + countOne--; + countTwo--; + } + } + countOne = 0; + countTwo = 0; + for (int num : nums) { + if (candidateOne != null && candidateOne == num) { + countOne++; + } + if (candidateTwo != null && candidateTwo == num) { + countTwo++; + } + } + int n = nums.length; + List result = new ArrayList<>(); + if (countOne > n / 3) { + result.add(candidateOne); + } + if (countTwo > n / 3) { + result.add(candidateTwo); + } + return result; } - List result = new ArrayList<>(); - countOne = 0; - countTwo = 0; - for (int num : nums) { - if (candidateOne != null && candidateOne == num) { - countOne++; - } - else if (candidateTwo != null && candidateTwo == num) { - countTwo++; - } - } - if (countOne > nums.length / 3) { - result.add(candidateOne); - } - if (countTwo > nums.length / 3) { - result.add(candidateTwo); - } - return result; - } } diff --git a/Medium/Make String a Subsequence Using Cyclic Increments.java b/Medium/Make String a Subsequence Using Cyclic Increments.java new file mode 100644 index 00000000..1247a755 --- /dev/null +++ b/Medium/Make String a Subsequence Using Cyclic Increments.java @@ -0,0 +1,18 @@ +class Solution { + public boolean canMakeSubsequence(String str1, String str2) { + int idxOne = 0; + int idxTwo = 0; + while (idxOne < str1.length() && idxTwo < str2.length()) { + if (str1.charAt(idxOne) == str2.charAt(idxTwo) || + nextCyclicChar(str1.charAt(idxOne)) == str2.charAt(idxTwo)) { + idxTwo++; + } + idxOne++; + } + return idxTwo == str2.length(); + } + + private static char nextCyclicChar(char c) { + return c == 'z' ? 'a' : (char) (c + 1); + } +} diff --git a/Medium/Make Sum Divisible by P.java b/Medium/Make Sum Divisible by P.java new file mode 100644 index 00000000..ee94817a --- /dev/null +++ b/Medium/Make Sum Divisible by P.java @@ -0,0 +1,26 @@ +class Solution { + public int minSubarray(int[] nums, int p) { + int n = nums.length; + int sum = 0; + for (int num : nums) { + sum = (sum + num) % p; + } + int target = sum % p; + if (target == 0) { + return 0; + } + Map map = new HashMap<>(); + map.put(0, -1); + int currSum = 0; + int result = n; + for (int i = 0; i < n; i++) { + currSum = (currSum + nums[i]) % p; + int needed = (currSum - target + p) % p; + if (map.containsKey(needed)) { + result = Math.min(result, i - map.get(needed)); + } + map.put(currSum, i); + } + return result == n ? -1 : result; + } +} diff --git a/Medium/Masking Personal Information.java b/Medium/Masking Personal Information.java index 841240a6..1d0559dc 100644 --- a/Medium/Masking Personal Information.java +++ b/Medium/Masking Personal Information.java @@ -1,76 +1,34 @@ class Solution { - public static String maskPII(String S) { - if (S.length() == 0) { - return S; - } - - if (S.indexOf('@') != -1) { - return formatEmail(S); - } - else { - return formatNumber(S); - } - } - - private static String formatNumber(String s) { - StringBuilder sb = new StringBuilder(); - int digitCount = getDigitCount(s); - - if (digitCount > 10) { - sb.append("+"); - int extra = digitCount - 10; - while (extra-- > 0) { - sb.append("*"); - } - sb.append("-"); - } - sb.append("***-***-"); - - StringBuilder last4 = new StringBuilder(); - for (int i=s.length()-1; i>=0; i--) { - if (Character.isDigit(s.charAt(i))) { - last4.append(s.charAt(i)); - } - - if (last4.length() == 4) { - break; - } - } - - sb.append(last4.reverse().toString()); - - return sb.toString(); - } - - private static int getDigitCount(String s) { - char[] chars = s.toCharArray(); - int count = 0; - - for (char c : chars) { - if (Character.isDigit(c)) { - count++; - } - } - - return count; - } - - private static String formatEmail(String s) { - int idx = s.indexOf('@'); - int revStart = idx - 1; - while (revStart >= 0 && Character.isLetter(s.charAt(revStart))) { - revStart--; - } - - StringBuilder sb = new StringBuilder(); - - sb. - append(s.substring(0, revStart+1)). - append(Character.toLowerCase(s.charAt(revStart + 1))). - append("*****"). - append(Character.toLowerCase(s.charAt(s.indexOf('@') - 1))). - append(s.substring(s.indexOf('@'))); - - return sb.toString().toLowerCase(); + public String maskPII(String s) { + return s.indexOf('@') != -1 ? maskEmail(s) : maskPhoneNumber(s); + } + + private String maskPhoneNumber(String phoneNumber) { + StringBuilder digits = new StringBuilder(); + for (char c : phoneNumber.toCharArray()) { + if (Character.isDigit(c)) { + digits.append(c); + } } + return getMaskedAreaCode(digits.length()) + "***-***-" + digits.substring(digits.length() - 4); + } + + private String getMaskedAreaCode(int phoneNumberLength) { + return switch (phoneNumberLength) { + case 10 -> ""; + case 11 -> "+*-"; + case 12 -> "+**-"; + case 13 -> "+***-"; + default -> null; + }; + } + + private String maskEmail(String email) { + String[] split = email.split("@"); + String name = split[0]; + String domain = split[1].toLowerCase(); + String maskedName = Character.toLowerCase(name.charAt(0)) + String.join("", Collections.nCopies(5, "*")) + + Character.toLowerCase(name.charAt(name.length() - 1)); + return maskedName + "@" + domain; + } } diff --git a/Medium/Matchsticks to Square.java b/Medium/Matchsticks to Square.java new file mode 100644 index 00000000..b5de023b --- /dev/null +++ b/Medium/Matchsticks to Square.java @@ -0,0 +1,32 @@ +class Solution { + public boolean makesquare(int[] matchsticks) { + int n = matchsticks.length; + int sum = 0; + for (int stick : matchsticks) { + sum += stick; + } + int possibleSide = sum / 4; + if (possibleSide * 4 != sum) { + return false; + } + Arrays.sort(matchsticks); + return dfs(new int[4], matchsticks, possibleSide, matchsticks.length - 1); + } + + private boolean dfs(int[] sum, int[] sticks, int possibleSide, int idx) { + if (idx == -1) { + return sum[0] == sum[1] && sum[1] == sum[2] && sum[2] == sum[3]; + } + int stick = sticks[idx]; + for (int i = 0; i < 4; i++) { + if (sum[i] + stick <= possibleSide) { + sum[i] += stick; + if (dfs(sum, sticks, possibleSide, idx - 1)) { + return true; + } + sum[i] -= stick; + } + } + return false; + } +} diff --git a/Medium/Max Area of Island.java b/Medium/Max Area of Island.java new file mode 100644 index 00000000..b7fc94ba --- /dev/null +++ b/Medium/Max Area of Island.java @@ -0,0 +1,34 @@ +class Solution { + private final int[][] DIRS = {{1, 0}, {0, 1}, {0, -1}, {-1, 0}}; + + public int maxAreaOfIsland(int[][] grid) { + int area = 0; + int rows = grid.length; + int cols = grid[0].length; + boolean[][] visited = new boolean[rows][cols]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (!visited[i][j] && grid[i][j] == 1) { + Queue queue = new LinkedList<>(); + int currArea = 0; + queue.add(new int[]{i, j}); + visited[i][j] = true; + while (!queue.isEmpty()) { + int[] removed = queue.remove(); + currArea++; + for (int[] dir : DIRS) { + int x = removed[0] + dir[0]; + int y = removed[1] + dir[1]; + if (x >= 0 && y >= 0 && x < rows && y < cols && !visited[x][y] && grid[x][y] == 1) { + queue.add(new int[]{x, y}); + visited[x][y] = true; + } + } + } + area = Math.max(area, currArea); + } + } + } + return area; + } +} diff --git a/Medium/Max Consecutive Ones III.java b/Medium/Max Consecutive Ones III.java new file mode 100644 index 00000000..cec14a87 --- /dev/null +++ b/Medium/Max Consecutive Ones III.java @@ -0,0 +1,23 @@ +class Solution { + public int longestOnes(int[] nums, int k) { + int start = 0; + int end = 0; + int flipped = 0; + int n = nums.length; + int max = 0; + while (end < nums.length) { + if (nums[end] == 0) { + flipped++; + } + end++; + while (start < end && flipped > k) { + if (nums[start] == 0) { + flipped--; + } + start++; + } + max = Math.max(max, end - start); + } + return max; + } +} diff --git a/Medium/Max Number of K-Sum Pairs.java b/Medium/Max Number of K-Sum Pairs.java new file mode 100644 index 00000000..fa942c0e --- /dev/null +++ b/Medium/Max Number of K-Sum Pairs.java @@ -0,0 +1,15 @@ +class Solution { + public int maxOperations(int[] nums, int k) { + Map map = new HashMap<>(); + int count = 0; + for (int num : nums) { + if (map.getOrDefault(k - num, 0) > 0) { + count++; + map.put(k - num, map.getOrDefault(k - num, 0) - 1); + } else { + map.put(num, map.getOrDefault(num, 0) + 1); + } + } + return count; + } +} diff --git a/Medium/Max Sum of a Pair With Equal Sum of Digits.java b/Medium/Max Sum of a Pair With Equal Sum of Digits.java new file mode 100644 index 00000000..1d8d89ae --- /dev/null +++ b/Medium/Max Sum of a Pair With Equal Sum of Digits.java @@ -0,0 +1,25 @@ +class Solution { + public int maximumSum(int[] nums) { + Map map = new HashMap<>(); + int maxSum = -1; + for (int num : nums) { + int digitSum = calculateDigitSum(num); + if (map.containsKey(digitSum)) { + maxSum = Math.max(maxSum, map.get(digitSum) + num); + map.put(digitSum, Math.max(map.get(digitSum), num)); + } else { + map.put(digitSum, num); + } + } + return maxSum; + } + + private int calculateDigitSum(int num) { + int sum = 0; + while (num > 0) { + sum += num % 10; + num /= 10; + } + return sum; + } +} diff --git a/Medium/Maximal Network Rank.java b/Medium/Maximal Network Rank.java new file mode 100644 index 00000000..e5c3f20c --- /dev/null +++ b/Medium/Maximal Network Rank.java @@ -0,0 +1,21 @@ +class Solution { + public int maximalNetworkRank(int n, int[][] roads) { + Map> map = new HashMap<>(); + for (int[] road : roads) { + map.computeIfAbsent(road[0], k -> new HashSet<>()).add(road[1]); + map.computeIfAbsent(road[1], k -> new HashSet<>()).add(road[0]); + } + int maximumRank = 0; + for (int i = 0; i < n; i++) { + int iRank = map.getOrDefault(i, new HashSet<>()).size(); + for (int j = i + 1; j < n; j++) { + int combinedRank = iRank + map.getOrDefault(j, new HashSet<>()).size(); + if (map.getOrDefault(j, new HashSet<>()).contains(i)) { + combinedRank--; + } + maximumRank = Math.max(maximumRank, combinedRank); + } + } + return maximumRank; + } +} diff --git a/Medium/Maximal Score After Applying K Operations.java b/Medium/Maximal Score After Applying K Operations.java new file mode 100644 index 00000000..ca776caf --- /dev/null +++ b/Medium/Maximal Score After Applying K Operations.java @@ -0,0 +1,15 @@ +class Solution { + public long maxKelements(int[] nums, int k) { + PriorityQueue pq = new PriorityQueue<>((a, b) -> b - a); + for (int num : nums) { + pq.add(num); + } + long sum = 0; + while (!pq.isEmpty() && k-- > 0) { + int removed = pq.poll(); + sum += removed; + pq.add((int) Math.ceil(((double) removed) / 3)); + } + return sum; + } +} diff --git a/Medium/Maximize Distance to Closest Person.java b/Medium/Maximize Distance to Closest Person.java new file mode 100644 index 00000000..8816dda5 --- /dev/null +++ b/Medium/Maximize Distance to Closest Person.java @@ -0,0 +1,14 @@ +class Solution { + public int maxDistToClosest(int[] seats) { + int n = seats.length; + int maxDistance = 0; + int start = -1; + for (int i = 0; i < n; i++) { + if (seats[i] == 1) { + maxDistance = start == -1 ? i : Math.max(maxDistance, (i - start) / 2); + start = i; + } + } + return Math.max(maxDistance, n - 1 - start); + } +} diff --git a/Medium/Maximize Happiness of Selected Children.java b/Medium/Maximize Happiness of Selected Children.java new file mode 100644 index 00000000..01e3aeff --- /dev/null +++ b/Medium/Maximize Happiness of Selected Children.java @@ -0,0 +1,15 @@ +class Solution { + public long maximumHappinessSum(int[] happiness, int k) { + Arrays.sort(happiness); + int turnCount = 0; + long happinessSum = 0; + int idx = happiness.length - 1; + while (k-- > 0) { + int currentHappiness = Math.max(0, happiness[idx] - turnCount); + happinessSum += currentHappiness; + turnCount++; + idx--; + } + return happinessSum; + } +} diff --git a/Medium/Maximize Number of Subsequences in a String.java b/Medium/Maximize Number of Subsequences in a String.java new file mode 100644 index 00000000..c2c26208 --- /dev/null +++ b/Medium/Maximize Number of Subsequences in a String.java @@ -0,0 +1,17 @@ +class Solution { + public long maximumSubsequenceCount(String text, String pattern) { + long result = 0; + int countCharOne = 0; + int countCharTwo = 0; + for (char c : text.toCharArray()) { + if (c == pattern.charAt(1)) { + result += countCharOne; + countCharTwo++; + } + if (c == pattern.charAt(0)) { + countCharOne++; + } + } + return result + Math.max(countCharOne, countCharTwo); + } +} diff --git a/Medium/Maximize the Confusion of an Exam.java b/Medium/Maximize the Confusion of an Exam.java new file mode 100644 index 00000000..3e7e14d1 --- /dev/null +++ b/Medium/Maximize the Confusion of an Exam.java @@ -0,0 +1,19 @@ +class Solution { + public int maxConsecutiveAnswers(String answerKey, int k) { + int resultSize = k; + Map map = new HashMap<>(); + for (int i = 0; i < k; i++) { + map.put(answerKey.charAt(i), map.getOrDefault(answerKey.charAt(i), 0) + 1); + } + int start = 0; + for (int i = k; i < answerKey.length(); i++) { + map.put(answerKey.charAt(i), map.getOrDefault(answerKey.charAt(i), 0) + 1); + while (Math.min(map.getOrDefault('T', 0), map.getOrDefault('F', 0)) > k) { + map.put(answerKey.charAt(start), map.get(answerKey.charAt(start)) - 1); + start++; + } + resultSize = Math.max(resultSize, i - start + 1); + } + return resultSize; + } +} diff --git a/Medium/Maximize the Topmost Element After K Moves.java b/Medium/Maximize the Topmost Element After K Moves.java new file mode 100644 index 00000000..d8bb4948 --- /dev/null +++ b/Medium/Maximize the Topmost Element After K Moves.java @@ -0,0 +1,17 @@ +class Solution { + public int maximumTop(int[] nums, int k) { + if (nums.length == 1) { + return k % 2 == 1 ? -1 : nums[0]; + } + int maxTop = -1; + if (k < nums.length) { + maxTop = nums[k]; + } else if (k > nums.length) { + k = nums.length + 1; + } + for (int i = 0; i < k - 1; i++) { + maxTop = Math.max(maxTop, nums[i]); + } + return maxTop; + } +} diff --git a/Medium/Maximum Absolute Sum of Any Subarray.java b/Medium/Maximum Absolute Sum of Any Subarray.java new file mode 100644 index 00000000..0dbca0d6 --- /dev/null +++ b/Medium/Maximum Absolute Sum of Any Subarray.java @@ -0,0 +1,15 @@ +class Solution { + public int maxAbsoluteSum(int[] nums) { + int currMax = nums[0]; + int max = currMax; + int currMin = nums[0]; + int min = currMin; + for(int i = 1; i < nums.length; i++){ + currMax = Math.max(nums[i], currMax + nums[i]); + max = Math.max(max, currMax); + currMin = Math.min(nums[i], currMin + nums[i]); + min = Math.min(min, currMin); + } + return Math.max(max, Math.abs(min)); + } +} diff --git a/Medium/Maximum Area of a Piece of Cake After Horizontal and Vertical Cuts.java b/Medium/Maximum Area of a Piece of Cake After Horizontal and Vertical Cuts.java new file mode 100644 index 00000000..e723cd7e --- /dev/null +++ b/Medium/Maximum Area of a Piece of Cake After Horizontal and Vertical Cuts.java @@ -0,0 +1,17 @@ +class Solution { + public int maxArea(int h, int w, int[] horizontalCuts, int[] verticalCuts) { + Arrays.sort(horizontalCuts); + Arrays.sort(verticalCuts); + int n = horizontalCuts.length; + int m = verticalCuts.length; + long maxHeight = Math.max(horizontalCuts[0], h - horizontalCuts[n - 1]); + for (int i = 1; i < n; i++) { + maxHeight = Math.max(maxHeight, horizontalCuts[i] - horizontalCuts[i - 1]); + } + long maxWidth = Math.max(verticalCuts[0], w - verticalCuts[m - 1]); + for (int i = 1; i < m; i++) { + maxWidth = Math.max(maxWidth, verticalCuts[i] - verticalCuts[i - 1]); + } + return (int) ((maxWidth * maxHeight) % (1000000007)); + } +} diff --git a/Medium/Maximum Average Subtree.java b/Medium/Maximum Average Subtree.java index 97c54cf6..873f4f01 100644 --- a/Medium/Maximum Average Subtree.java +++ b/Medium/Maximum Average Subtree.java @@ -4,28 +4,32 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - double maxAvg; - public double maximumAverageSubtree(TreeNode root) { - maxAvg = 0.0; - helper(root); - return maxAvg; - } - - private int[] helper(TreeNode root) { - int[] data = new int[2]; - if (root == null) { - return data; + public double maximumAverageSubtree(TreeNode root) { + double[] result = {0.0}; + traverse(root, result); + return result[0]; + } + + private double[] traverse(TreeNode root, double[] result) { + if (root == null) { + return new double[]{0.0, 0.0}; + } + double[] leftValues = traverse(root.left, result); + double[] rightValues = traverse(root.right, result); + double sum = root.val + leftValues[0] + rightValues[0]; + double count = 1 + leftValues[1] + rightValues[1]; + double avg = sum / count; + result[0] = Math.max(result[0], avg); + return new double[]{sum, count}; } - int[] dataLeft = helper(root.left); - int[] dataRight = helper(root.right); - data[0] += root.val + dataLeft[0] + dataRight[0]; - data[1] += 1 + dataLeft[1] + dataRight[1]; - double avg = ((double) data[0]) / data[1]; - maxAvg = Math.max(maxAvg, avg); - return data; - } } diff --git a/Medium/Maximum Bags With Full Capacity of Rocks.java b/Medium/Maximum Bags With Full Capacity of Rocks.java new file mode 100644 index 00000000..e73a7826 --- /dev/null +++ b/Medium/Maximum Bags With Full Capacity of Rocks.java @@ -0,0 +1,15 @@ +class Solution { + public int maximumBags(int[] capacity, int[] rocks, int additionalRocks) { + PriorityQueue pq = new PriorityQueue<>(); + for (int i = 0; i < capacity.length; i++) { + pq.add(capacity[i] - rocks[i]); + } + while (!pq.isEmpty()) { + if (pq.peek() > additionalRocks) { + return capacity.length - pq.size(); + } + additionalRocks -= pq.poll(); + } + return capacity.length; + } +} diff --git a/Medium/Maximum Coins Heroes Can Collect.java b/Medium/Maximum Coins Heroes Can Collect.java new file mode 100644 index 00000000..1e98abf9 --- /dev/null +++ b/Medium/Maximum Coins Heroes Can Collect.java @@ -0,0 +1,40 @@ +class Solution { + public long[] maximumCoins(int[] heroes, int[] monsters, int[] coins) { + List monsterEntities = new ArrayList<>(); + int n = monsters.length; + for (int i = 0; i < n; i++) { + monsterEntities.add(new MonsterEntity(monsters[i], coins[i])); + } + Collections.sort(monsterEntities, (a, b) -> (a.health() - b.health())); + long[] prefixCoinSum = new long[n]; + for (int i = 0; i < n; i++) { + prefixCoinSum[i] = i == 0 ? 0 : prefixCoinSum[i - 1]; + prefixCoinSum[i] += monsterEntities.get(i).coin(); + } + int m = heroes.length; + long[] result = new long[m]; + for (int i = 0; i < m; i++) { + int idx = binarySearch(monsterEntities, heroes[i]); + result[i] = idx != Integer.MIN_VALUE ? prefixCoinSum[idx] : 0; + } + return result; + } + + private int binarySearch(List monsterEntities, int heroHealth) { + int left = 0; + int right = monsterEntities.size() - 1; + int idx = Integer.MIN_VALUE; + while (left <= right) { + int mid = (left + right) / 2; + if (monsterEntities.get(mid).health() <= heroHealth) { + idx = Math.max(idx, mid); + left = mid + 1; + } else { + right = mid - 1; + } + } + return idx; + } + + private static record MonsterEntity(int health, int coin) {} +} diff --git a/Medium/Maximum Consecutive Floors Without Special Floors.java b/Medium/Maximum Consecutive Floors Without Special Floors.java new file mode 100644 index 00000000..8d33dc1e --- /dev/null +++ b/Medium/Maximum Consecutive Floors Without Special Floors.java @@ -0,0 +1,12 @@ +class Solution { + public int maxConsecutive(int bottom, int top, int[] special) { + Arrays.sort(special); + int maxConsecutiveFloors = Math.max(special[0] - bottom, top - special[special.length - 1]); + for (int specialFloor : special) { + int emptyFloors = specialFloor - bottom; + bottom = specialFloor + 1; + maxConsecutiveFloors = Math.max(maxConsecutiveFloors, emptyFloors); + } + return maxConsecutiveFloors; + } +} diff --git a/Medium/Maximum Difference Between Node and Ancestor.java b/Medium/Maximum Difference Between Node and Ancestor.java new file mode 100644 index 00000000..b623f146 --- /dev/null +++ b/Medium/Maximum Difference Between Node and Ancestor.java @@ -0,0 +1,51 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public int maxAncestorDiff(TreeNode root) { + int maxDiff = 0; + Queue queue = new LinkedList<>(); + queue.add(new NodeValuePair(root, root.val, root.val)); + while (!queue.isEmpty()) { + NodeValuePair removed = queue.remove(); + TreeNode node = removed.node; + Integer minNodeValue = removed.minNodeValue; + Integer maxNodeValue = removed.maxNodeValue; + maxDiff = Math.max(maxDiff, Math.max(Math.abs(node.val - minNodeValue), Math.abs(node.val - maxNodeValue))); + Integer updatedMinNodeValue = Math.min(node.val, minNodeValue); + Integer updatedMaxNodeValue = Math.max(node.val, maxNodeValue); + if (node.left != null) { + queue.add(new NodeValuePair(node.left, updatedMinNodeValue, updatedMaxNodeValue)); + } + if (node.right != null) { + queue.add(new NodeValuePair(node.right, updatedMinNodeValue, updatedMaxNodeValue)); + } + } + return maxDiff; + } + + + private static class NodeValuePair { + private TreeNode node; + private Integer minNodeValue; + private Integer maxNodeValue; + + public NodeValuePair(TreeNode node, Integer minNodeValue, Integer maxNodeValue) { + this.node = node; + this.minNodeValue = minNodeValue; + this.maxNodeValue = maxNodeValue; + } + } +} diff --git a/Medium/Maximum Distance Between a Pair of Values.java b/Medium/Maximum Distance Between a Pair of Values.java new file mode 100644 index 00000000..f0388ec4 --- /dev/null +++ b/Medium/Maximum Distance Between a Pair of Values.java @@ -0,0 +1,26 @@ +class Solution { + public int maxDistance(int[] nums1, int[] nums2) { + int maxDistance = 0; + for (int i = 0; i < nums1.length; i++) { + int idx = getValidIdx(nums2, i, nums2.length - 1, nums1[i]); + if (idx != -1) { + maxDistance = Math.max(maxDistance, idx - i); + } + } + return maxDistance; + } + + private int getValidIdx(int[] nums, int start, int end, int limit) { + int idx = -1; + while (start <= end) { + int mid = (start + end) / 2; + if (nums[mid] >= limit) { + idx = Math.max(idx, mid); + start = mid + 1; + } else { + end = mid - 1; + } + } + return idx; + } +} diff --git a/Medium/Maximum Distance in Arrays.java b/Medium/Maximum Distance in Arrays.java new file mode 100644 index 00000000..8205803e --- /dev/null +++ b/Medium/Maximum Distance in Arrays.java @@ -0,0 +1,17 @@ +class Solution { + public int maxDistance(List> arrays) { + int result = 0; + int n = arrays.get(0).size(); + int min = arrays.get(0).get(0); + int max = arrays.get(0).get(n - 1); + for (int i = 1; i < arrays.size(); i++) { + n = arrays.get(i).size(); + result = Math.max(result, + Math.max(Math.abs(arrays.get(i).get(n - 1) - min), + Math.abs(max - arrays.get(i).get(0)))); + min = Math.min(min, arrays.get(i).get(0)); + max = Math.max(max, arrays.get(i).get(n - 1)); + } + return result; + } +} diff --git a/Medium/Maximum Erasure Value.java b/Medium/Maximum Erasure Value.java new file mode 100644 index 00000000..ff897923 --- /dev/null +++ b/Medium/Maximum Erasure Value.java @@ -0,0 +1,21 @@ +class Solution { + public int maximumUniqueSubarray(int[] nums) { + int maximumSum = 0; + int currSum = 0; + int start = 0; + int end = 0; + int n = nums.length; + Map map = new HashMap<>(); + while (end < n) { + int currNum = nums[end++]; + map.put(currNum, map.getOrDefault(currNum, 0) + 1); + currSum += currNum; + while (start < end && map.get(currNum) > 1) { + map.put(nums[start], map.getOrDefault(nums[start], 0) - 1); + currSum -= nums[start++]; + } + maximumSum = Math.max(maximumSum, currSum); + } + return maximumSum; + } +} diff --git a/Medium/Maximum Ice Cream Bars.java b/Medium/Maximum Ice Cream Bars.java new file mode 100644 index 00000000..d8faca38 --- /dev/null +++ b/Medium/Maximum Ice Cream Bars.java @@ -0,0 +1,18 @@ +class Solution { + public int maxIceCream(int[] costs, int coins) { + int[] costFrequency = new int[1000_01]; + for (int cost : costs) { + costFrequency[cost]++; + } + int numberOfIcecreams = 0; + for (int i = 1; i <= 1000_00 && coins >= i; i++) { + if (costFrequency[i] > 0) { + while (coins >= i && costFrequency[i]-- > 0) { + numberOfIcecreams++; + coins -= i; + } + } + } + return numberOfIcecreams; + } +} diff --git a/Medium/Maximum Length of Pair Chain.java b/Medium/Maximum Length of Pair Chain.java index 1ad30427..cb98b670 100644 --- a/Medium/Maximum Length of Pair Chain.java +++ b/Medium/Maximum Length of Pair Chain.java @@ -1,22 +1,14 @@ class Solution { public int findLongestChain(int[][] pairs) { - Arrays.sort(pairs, new Comparator() { - @Override - public int compare(int[] o1, int[] o2) { - return o1[0] - o2[0]; - } - }); - - int[] temp = new int[pairs.length]; - Arrays.fill(temp, 1); - for (int i=1; i a[1])); + int curr = Integer.MIN_VALUE; + int result = 0; + for (int[] pair : pairs) { + if (pair[0] > curr) { + result++; + curr = pair[1]; } } - - return Arrays.stream(temp).max().getAsInt(); + return result; } } diff --git a/Medium/Maximum Length of Repeated Subarray.java b/Medium/Maximum Length of Repeated Subarray.java new file mode 100644 index 00000000..af6696fb --- /dev/null +++ b/Medium/Maximum Length of Repeated Subarray.java @@ -0,0 +1,15 @@ +class Solution { + public int findLength(int[] nums1, int[] nums2) { + int result = 0; + int[][] dp = new int[nums1.length + 1][nums2.length + 1]; + for (int i = nums1.length - 1; i >= 0; i--) { + for (int j = nums2.length - 1; j >= 0; j--) { + if (nums1[i] == nums2[j]) { + dp[i][j] = dp[i + 1][j + 1] + 1; + result = Math.max(result, dp[i][j]); + } + } + } + return result; + } +} diff --git a/Medium/Maximum Length of a Concatenated String with Unique Characters.java b/Medium/Maximum Length of a Concatenated String with Unique Characters.java new file mode 100644 index 00000000..65ca06dc --- /dev/null +++ b/Medium/Maximum Length of a Concatenated String with Unique Characters.java @@ -0,0 +1,26 @@ +class Solution { + public int maxLength(List arr) { + return backtrack(arr, 0, new HashMap<>()); + } + + private int backtrack(List arr, int idx, Map map) { + if (map.values().stream().anyMatch(val -> val > 1)) { + return 0; + } + int result = map.size(); + for (int i = idx; i < arr.size(); i++) { + char[] chars = arr.get(i).toCharArray(); + for (char c : chars) { + map.put(c, map.getOrDefault(c, 0) + 1); + } + result = Math.max(result, backtrack(arr, i + 1, map)); + for (char c : chars) { + map.put(c, map.get(c) - 1); + if (map.get(c) == 0) { + map.remove(c); + } + } + } + return result; + } +} diff --git a/Medium/Maximum Level Sum of a Binary Tree.java b/Medium/Maximum Level Sum of a Binary Tree.java index 8c1bdac6..74c62767 100644 --- a/Medium/Maximum Level Sum of a Binary Tree.java +++ b/Medium/Maximum Level Sum of a Binary Tree.java @@ -14,34 +14,31 @@ * } */ class Solution { - public int maxLevelSum(TreeNode root) { - if (root == null) { - return 0; - } - int currLevel = 1; - int maxSum = Integer.MIN_VALUE; - int maxSumLevel = 0; - Queue queue = new LinkedList<>(); - queue.add(root); - while (!queue.isEmpty()) { - int size = queue.size(); - int currSum = 0; - while (size-- > 0) { - TreeNode removed = queue.remove(); - currSum += removed.val; - if (removed.left != null) { - queue.add(removed.left); - } - if (removed.right != null) { - queue.add(removed.right); + public int maxLevelSum(TreeNode root) { + int maxSum = Integer.MIN_VALUE; + int maxSumLevel = 0; + int currLevel = 1; + Queue queue = new LinkedList<>(); + queue.add(root); + while (!queue.isEmpty()) { + int levelSum = 0; + int size = queue.size(); + while (size-- > 0) { + TreeNode removed = queue.remove(); + levelSum += removed.val; + if (removed.left != null) { + queue.add(removed.left); + } + if (removed.right != null) { + queue.add(removed.right); + } + } + if (levelSum > maxSum) { + maxSum = levelSum; + maxSumLevel = currLevel; + } + currLevel++; } - } - if (maxSum < currSum) { - maxSum = currSum; - maxSumLevel = currLevel; - } - currLevel++; + return maxSumLevel; } - return maxSumLevel; - } } diff --git a/Medium/Maximum Matching of Players With Trainers.java b/Medium/Maximum Matching of Players With Trainers.java new file mode 100644 index 00000000..5334f4e5 --- /dev/null +++ b/Medium/Maximum Matching of Players With Trainers.java @@ -0,0 +1,15 @@ +class Solution { + public int matchPlayersAndTrainers(int[] players, int[] trainers) { + Arrays.sort(players); + Arrays.sort(trainers); + int playerIdx = 0; + int trainerIdx = 0; + while (playerIdx < players.length && trainerIdx < trainers.length) { + if (players[playerIdx] <= trainers[trainerIdx]) { + playerIdx++; + } + trainerIdx++; + } + return playerIdx; + } +} diff --git a/Medium/Maximum Nesting Depth of Two Valid Parentheses Strings.java b/Medium/Maximum Nesting Depth of Two Valid Parentheses Strings.java new file mode 100644 index 00000000..df70bcb7 --- /dev/null +++ b/Medium/Maximum Nesting Depth of Two Valid Parentheses Strings.java @@ -0,0 +1,11 @@ +class Solution { + public int[] maxDepthAfterSplit(String seq) { + int[] result = new int[seq.length()]; + int idx = 0; + int depth = 0; + for (char c : seq.toCharArray()) { + result[idx++] = c == '(' ? (depth++ % 2) : (--depth % 2); + } + return result; + } +} diff --git a/Medium/Maximum Number of Coins You Can Get.java b/Medium/Maximum Number of Coins You Can Get.java new file mode 100644 index 00000000..7642d7e2 --- /dev/null +++ b/Medium/Maximum Number of Coins You Can Get.java @@ -0,0 +1,11 @@ +class Solution { + public int maxCoins(int[] piles) { + Arrays.sort(piles); + int n = piles.length; + int maxCoinCount = 0; + for (int i = n / 3; i < n; i += 2) { + maxCoinCount += piles[i]; + } + return maxCoinCount; + } +} diff --git a/Medium/Maximum Number of Events That Can Be Attended.java b/Medium/Maximum Number of Events That Can Be Attended.java new file mode 100644 index 00000000..a69653b5 --- /dev/null +++ b/Medium/Maximum Number of Events That Can Be Attended.java @@ -0,0 +1,22 @@ +class Solution { + public int maxEvents(int[][] events) { + Arrays.sort(events, (a, b) -> a[0] - b[0]); + PriorityQueue pq = new PriorityQueue<>(); + int idx = 0; + int numOfEventsAttended = 0; + int n = events.length; + for (int currDay = 1; currDay <= 100000; currDay++) { + while (!pq.isEmpty() && pq.peek() < currDay) { + pq.poll(); + } + while (idx < n && events[idx][0] == currDay) { + pq.add(events[idx++][1]); + } + if (!pq.isEmpty()) { + pq.poll(); + numOfEventsAttended++; + } + } + return numOfEventsAttended; + } +} diff --git a/Medium/Maximum Number of Groups Entering a Competition.java b/Medium/Maximum Number of Groups Entering a Competition.java new file mode 100644 index 00000000..a1794f7a --- /dev/null +++ b/Medium/Maximum Number of Groups Entering a Competition.java @@ -0,0 +1,13 @@ +class Solution { + public int maximumGroups(int[] grades) { + int numOfGroups = 0; + int n = grades.length; + int groupSize = 1; + int totalGrades = 0; + while (totalGrades < n) { + totalGrades += ++groupSize; + numOfGroups++; + } + return numOfGroups; + } +} diff --git a/Medium/Maximum Number of Integers to Choose From a Range I.java b/Medium/Maximum Number of Integers to Choose From a Range I.java new file mode 100644 index 00000000..8f3ad2ee --- /dev/null +++ b/Medium/Maximum Number of Integers to Choose From a Range I.java @@ -0,0 +1,17 @@ +class Solution { + public int maxCount(int[] banned, int n, int maxSum) { + int count = 0; + Set bannedSet = Arrays.stream(banned).boxed().collect(Collectors.toSet()); + for (int i = 1; i <= n && count < n; i++) { + if (bannedSet.contains(i)) { + continue; + } + if (maxSum - i < 0) { + break; + } + count++; + maxSum -= i; + } + return count; + } +} diff --git a/Medium/Maximum Number of Moves in a Grid.java b/Medium/Maximum Number of Moves in a Grid.java new file mode 100644 index 00000000..014425f8 --- /dev/null +++ b/Medium/Maximum Number of Moves in a Grid.java @@ -0,0 +1,40 @@ +class Solution { + + private static final int[] DIRS = {-1, 0, 1}; + + public int maxMoves(int[][] grid) { + int rows = grid.length; + int cols = grid[0].length; + Queue queue = new LinkedList<>(); + boolean[][] visited = new boolean[rows][cols]; + for (int i = 0; i < rows; i++) { + visited[i][0] = true; + queue.add(new int[]{i, 0, 0}); + } + int result = 0; + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + int[] removed = queue.remove(); + int row = removed[0]; + int col = removed[1]; + int count = removed[2]; + result = Math.max(result, count); + for (int dir : DIRS) { + int nextRow = row + dir; + int nextCol = col + 1; + if (nextRow >= 0 && + nextCol >= 0 && + nextRow < rows && + nextCol < cols && + !visited[nextRow][nextCol] && + grid[row][col] < grid[nextRow][nextCol]) { + visited[nextRow][nextCol] = true; + queue.add(new int[]{nextRow, nextCol, count + 1}); + } + } + } + } + return result; + } +} diff --git a/Medium/Maximum Number of Occurrences of a Substring.java b/Medium/Maximum Number of Occurrences of a Substring.java index 6d957c4f..f0f56202 100644 --- a/Medium/Maximum Number of Occurrences of a Substring.java +++ b/Medium/Maximum Number of Occurrences of a Substring.java @@ -1,31 +1,24 @@ class Solution { public int maxFreq(String s, int maxLetters, int minSize, int maxSize) { - int n = s.length(); - if (minSize > n) { - return 0; - } - Map substringMap = new HashMap<>(); - for (int i = 0; i < n; i++) { - Map charMap = new HashMap<>(); - for (int j = 0; j < maxSize; j++) { - if (i + j >= n) { - break; - } - charMap.put(s.charAt(i + j), charMap.getOrDefault(s.charAt(i + j), 0) + 1); - if (charMap.size() > maxLetters) { - break; - } - if (j >= minSize - 1) { - substringMap.put( - s.substring(i, i + j + 1), substringMap.getOrDefault(s.substring(i, i + j + 1), 0) + 1 - ); + Map letterFrequencyMap = new HashMap<>(); + Map substringFrequencyMap = new HashMap<>(); + int start = 0; + int maxCount = 0; + for (int i = 0; i < s.length(); i++) { + letterFrequencyMap.put(s.charAt(i), letterFrequencyMap.getOrDefault(s.charAt(i), 0) + 1); + while (i - start + 1 > minSize || letterFrequencyMap.size() > maxLetters) { + letterFrequencyMap.put(s.charAt(start), letterFrequencyMap.getOrDefault(s.charAt(start), 0) - 1); + if (letterFrequencyMap.get(s.charAt(start)) == 0) { + letterFrequencyMap.remove(s.charAt(start)); } + start++; + } + if (i - start + 1 == minSize) { + String currSubstring = s.substring(start, i + 1); + substringFrequencyMap.put(currSubstring, substringFrequencyMap.getOrDefault(currSubstring, 0) + 1); + maxCount = Math.max(maxCount, substringFrequencyMap.get(currSubstring)); } } - int maxFreqCount = 0; - for (String substr : substringMap.keySet()) { - maxFreqCount = Math.max(maxFreqCount, substringMap.get(substr)); - } - return maxFreqCount; + return maxCount; } } diff --git a/Medium/Maximum Number of Vowels in a Substring of Given Length.java b/Medium/Maximum Number of Vowels in a Substring of Given Length.java index 5af78c54..0b27eda9 100644 --- a/Medium/Maximum Number of Vowels in a Substring of Given Length.java +++ b/Medium/Maximum Number of Vowels in a Substring of Given Length.java @@ -1,32 +1,23 @@ class Solution { - public int maxVowels(String s, int k) { - Map map = new HashMap<>(); - String vowels = "aeiou"; - int count = 0; - int maxCount = 0; - int start = 0; - int end = 0; - int n = s.length(); - while (end < (k - 1)) { - if (vowels.indexOf(s.charAt(end)) != -1) { - map.put(s.charAt(end), map.getOrDefault(s.charAt(end), 0) + 1); - count++; - } - end++; + public int maxVowels(String s, int k) { + int currCount = 0; + Set vowels = Set.of('a', 'e', 'i', 'o', 'u'); + for (int i = 0; i < k - 1; i++) { + if (vowels.contains(s.charAt(i))) { + currCount++; + } + } + int maxCount = 0; + int start = 0; + for (int i = k - 1; i < s.length(); i++) { + if (vowels.contains(s.charAt(i))) { + currCount++; + } + maxCount = Math.max(maxCount, currCount); + if (vowels.contains(s.charAt(start++))) { + currCount--; + } + } + return maxCount; } - while (end < n) { - if (vowels.indexOf(s.charAt(end)) != -1) { - map.put(s.charAt(end), map.getOrDefault(s.charAt(end), 0) + 1); - count++; - } - end++; - maxCount = Math.max(maxCount, count); - if (vowels.indexOf(s.charAt(start)) != -1) { - map.put(s.charAt(start), map.getOrDefault(s.charAt(start), 0) - 1); - count--; - } - start++; - } - return maxCount; - } } diff --git a/Medium/Maximum Points After Enemy Battles.java b/Medium/Maximum Points After Enemy Battles.java new file mode 100644 index 00000000..2358cd8f --- /dev/null +++ b/Medium/Maximum Points After Enemy Battles.java @@ -0,0 +1,16 @@ +class Solution { + public long maximumPoints(int[] enemyEnergies, int currentEnergy) { + long sum = 0; + int minimumEnergy = Integer.MAX_VALUE; + for (int energy : enemyEnergies) { + sum += energy; + minimumEnergy = Math.min(minimumEnergy, energy); + } + if (currentEnergy < minimumEnergy) { + return 0; + } + long totalEnergy = currentEnergy; + totalEnergy += sum - minimumEnergy; + return totalEnergy / minimumEnergy; + } +} diff --git a/Medium/Maximum Points You Can Obtain from Cards.java b/Medium/Maximum Points You Can Obtain from Cards.java new file mode 100644 index 00000000..b9648446 --- /dev/null +++ b/Medium/Maximum Points You Can Obtain from Cards.java @@ -0,0 +1,17 @@ +class Solution { + public int maxScore(int[] cardPoints, int k) { + int n = cardPoints.length; + int[] prefixSum = new int[k + 1]; + int[] suffixSum = new int[k + 1]; + for (int i = 0; i < k; i++) { + prefixSum[i + 1] = cardPoints[i] + prefixSum[i]; + suffixSum[i + 1] = cardPoints[n - i - 1] + suffixSum[i]; + } + int result = 0; + for (int i = 0; i <= k; i++) { + int currScore = prefixSum[i] + suffixSum[k - i]; + result = Math.max(result, currScore); + } + return result; + } +} diff --git a/Medium/Maximum Product of Splitted Binary Tree.java b/Medium/Maximum Product of Splitted Binary Tree.java new file mode 100644 index 00000000..72a36750 --- /dev/null +++ b/Medium/Maximum Product of Splitted Binary Tree.java @@ -0,0 +1,37 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public int maxProduct(TreeNode root) { + List allNodeSums = new ArrayList<>(); + long totalSum = treeSum(root, allNodeSums); + long best = 0; + for (long sum : allNodeSums) { + best = Math.max(best, sum * (totalSum - sum)); + } + return (int) (best % 1000_000_007); + } + + private int treeSum(TreeNode root, List allNodeSums) { + if (root == null) { + return 0; + } + int leftSum = treeSum(root.left, allNodeSums); + int rightSum = treeSum(root.right, allNodeSums); + int totalSum = leftSum + rightSum + root.val; + allNodeSums.add(totalSum); + return totalSum; + } +} diff --git a/Medium/Maximum Product of Word Lengths.java b/Medium/Maximum Product of Word Lengths.java new file mode 100644 index 00000000..d98a03bb --- /dev/null +++ b/Medium/Maximum Product of Word Lengths.java @@ -0,0 +1,25 @@ +class Solution { + public int maxProduct(String[] words) { + int maxProd = 0; + for (int i = 0; i < words.length; i++) { + for (int j = i + 1; j < words.length; j++) { + if (noCommonLetters(words[i], words[j])) { + maxProd = Math.max(maxProd, words[i].length() * words[j].length()); + } + } + } + return maxProd; + } + + private boolean noCommonLetters(String s1, String s2) { + int bitMaskOne = 0; + int bitMaskTwo = 0; + for (char c : s1.toCharArray()) { + bitMaskOne |= 1 << ((int) c - (int) 'a'); + } + for (char c : s2.toCharArray()) { + bitMaskTwo |= 1 << ((int) c - (int) 'a'); + } + return (bitMaskOne & bitMaskTwo) == 0; + } +} diff --git a/Medium/Maximum Score From Removing Stones.java b/Medium/Maximum Score From Removing Stones.java new file mode 100644 index 00000000..bdc88bcb --- /dev/null +++ b/Medium/Maximum Score From Removing Stones.java @@ -0,0 +1,19 @@ +class Solution { + public int maximumScore(int a, int b, int c) { + PriorityQueue pq = new PriorityQueue<>(Collections.reverseOrder()); + pq.addAll(Arrays.asList(a, b, c)); + int score = 0; + while (pq.size() > 1) { + int firstStoneCount = pq.remove(); + int secondStoneCount = pq.remove(); + if (firstStoneCount > 1) { + pq.add(firstStoneCount - 1); + } + if (secondStoneCount > 1) { + pq.add(secondStoneCount - 1); + } + score++; + } + return score; + } +} diff --git a/Medium/Maximum Score From Removing Substrings.java b/Medium/Maximum Score From Removing Substrings.java new file mode 100644 index 00000000..0f7ccf87 --- /dev/null +++ b/Medium/Maximum Score From Removing Substrings.java @@ -0,0 +1,29 @@ +class Solution { + public int maximumGain(String s, int x, int y) { + int score = 0; + String firstPass = removeSubstring(s, x > y ? "ab" : "ba"); + int removeCount = (s.length() - firstPass.length()) / 2; + score += removeCount * Math.max(x, y); + String secondPass = removeSubstring(firstPass, x > y ? "ba" : "ab"); + removeCount = (firstPass.length() - secondPass.length()) / 2; + score += removeCount * Math.min(x, y); + return score; + } + + private String removeSubstring(String s, String target) { + Stack stack = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == target.charAt(1) && !stack.isEmpty() && stack.peek() == target.charAt(0)) { + stack.pop(); + } else { + stack.push(c); + } + } + StringBuilder sb = new StringBuilder(); + while (!stack.isEmpty()) { + sb.append(stack.pop()); + } + return sb.reverse().toString(); + } +} diff --git a/Medium/Maximum Score from Performing Multiplication Operations.java b/Medium/Maximum Score from Performing Multiplication Operations.java new file mode 100644 index 00000000..c197f348 --- /dev/null +++ b/Medium/Maximum Score from Performing Multiplication Operations.java @@ -0,0 +1,19 @@ +class Solution { + public int maximumScore(int[] nums, int[] multipliers) { + Integer[][] dp = new Integer[1001][1001]; + return helper(0, multipliers, nums, 0, dp); + } + + private int helper(int idx, int[] multipliers, int[] nums, int start, Integer[][] dp) { + if (idx == multipliers.length) { + return 0; + } + if (dp[idx][start] != null) { + return dp[idx][start]; + } + int end = nums.length - (idx - start) - 1; + int startOperation = multipliers[idx] * nums[start] + helper(idx + 1, multipliers, nums, start + 1, dp); + int endOperation = multipliers[idx] * nums[end] + helper(idx + 1, multipliers, nums, start, dp); + return dp[idx][start] = Math.max(startOperation, endOperation); + } +} diff --git a/Medium/Maximum Size Subarray Sum Equals k.java b/Medium/Maximum Size Subarray Sum Equals k.java index 97d37973..dce7007a 100644 --- a/Medium/Maximum Size Subarray Sum Equals k.java +++ b/Medium/Maximum Size Subarray Sum Equals k.java @@ -1,18 +1,17 @@ class Solution { - public int maxSubArrayLen(int[] nums, int k) { - Map map = new HashMap<>(); - int res = 0; - int sum = 0; - for (int i = 0; i < nums.length; i++) { - sum += nums[i]; - if (sum == k) { - res = i + 1; - } - else if (map.containsKey(sum - k)) { - res = Math.max(res, i - map.get(sum - k)); - } - map.putIfAbsent(sum, i); + public int maxSubArrayLen(int[] nums, int k) { + Map map = new HashMap<>(); + int prefixSum = 0; + int max = 0; + for (int i = 0; i < nums.length; i++) { + prefixSum += nums[i]; + if (prefixSum == k) { + max = i + 1; + } else if (map.containsKey(prefixSum - k)) { + max = Math.max(max, i - map.get(prefixSum - k)); + } + map.putIfAbsent(prefixSum, i); + } + return max; } - return res; - } } diff --git a/Medium/Maximum Star Sum of a Graph.java b/Medium/Maximum Star Sum of a Graph.java new file mode 100644 index 00000000..f54f2f83 --- /dev/null +++ b/Medium/Maximum Star Sum of a Graph.java @@ -0,0 +1,19 @@ +class Solution { + public int maxStarSum(int[] vals, int[][] edges, int k) { + Map> graph = new HashMap<>(); + for (int[] edge : edges) { + graph.computeIfAbsent(edge[0], node -> new PriorityQueue<>(Comparator.reverseOrder())).add(vals[edge[1]]); + graph.computeIfAbsent(edge[1], node -> new PriorityQueue<>(Comparator.reverseOrder())).add(vals[edge[0]]); + } + int maxSum = Integer.MIN_VALUE; + for (int i = 0; i < vals.length; i++) { + int currSum = vals[i]; + PriorityQueue pq = graph.getOrDefault(i, new PriorityQueue<>()); + for (int j = 0; j < k && !pq.isEmpty(); j++){ + currSum += Math.max(pq.poll(), 0); + } + maxSum = Math.max(maxSum, currSum); + } + return maxSum; + } +} diff --git a/Medium/Maximum Subarray.java b/Medium/Maximum Subarray.java new file mode 100644 index 00000000..459a8733 --- /dev/null +++ b/Medium/Maximum Subarray.java @@ -0,0 +1,14 @@ +class Solution { + public int maxSubArray(int[] nums) { + int currSum = 0; + int maxSum = Integer.MIN_VALUE; + for (int num : nums) { + currSum += num; + if (currSum < num) { + currSum = num; + } + maxSum = Math.max(maxSum, currSum); + } + return maxSum; + } +} diff --git a/Medium/Maximum Subsequence Score.java b/Medium/Maximum Subsequence Score.java new file mode 100644 index 00000000..2598f5ed --- /dev/null +++ b/Medium/Maximum Subsequence Score.java @@ -0,0 +1,23 @@ +class Solution { + public long maxScore(int[] nums1, int[] nums2, int k) { + int[][] combined = new int[nums1.length][2]; + for (int i = 0; i < nums1.length; i++) { + combined[i] = new int[]{nums1[i], nums2[i]}; + } + Arrays.sort(combined, (o1, o2) -> o2[1] - o1[1]); + long result = 0; + long total = 0; + PriorityQueue pq = new PriorityQueue<>(); + for (int[] unit : combined) { + pq.add(unit[0]); + total += unit[0]; + if (pq.size() > k) { + total -= pq.poll(); + } + if (pq.size() == k) { + result = Math.max(result, total * unit[1]); + } + } + return result; + } +} diff --git a/Medium/Maximum Sum of Almost Unique Subarray.java b/Medium/Maximum Sum of Almost Unique Subarray.java new file mode 100644 index 00000000..1d9facff --- /dev/null +++ b/Medium/Maximum Sum of Almost Unique Subarray.java @@ -0,0 +1,28 @@ +class Solution { + public long maxSum(List nums, int m, int k) { + long result = 0; + long currSum = 0; + Map frequencyMap = new HashMap<>(); + int uniqueCount = 0; + for (int i = 0; i < nums.size(); i++) { + int curr = nums.get(i); + frequencyMap.put(curr, frequencyMap.getOrDefault(curr, 0) + 1); + if (frequencyMap.get(curr) == 1) { + uniqueCount++; + } + currSum += curr; + if (i >= k - 1) { + if (uniqueCount >= m) { + result = Math.max(result, currSum); + } + int temp = nums.get(i - k + 1); + frequencyMap.put(temp, frequencyMap.getOrDefault(temp, 0) - 1); + if (frequencyMap.get(temp) == 0) { + uniqueCount--; + } + currSum -= temp; + } + } + return result; + } +} diff --git a/Medium/Maximum Sum of Distinct Subarrays With Length K.java b/Medium/Maximum Sum of Distinct Subarrays With Length K.java new file mode 100644 index 00000000..044ad0bd --- /dev/null +++ b/Medium/Maximum Sum of Distinct Subarrays With Length K.java @@ -0,0 +1,26 @@ +class Solution { + public long maximumSubarraySum(int[] nums, int k) { + Map map = new HashMap<>(); + long currSum = 0; + long maxSum = 0; + for (int i = 0; i < k - 1; i++) { + map.put(nums[i], map.getOrDefault(nums[i], 0) + 1); + currSum += nums[i]; + } + int startIdx = 0; + for (int i = k - 1; i < nums.length; i++) { + map.put(nums[i], map.getOrDefault(nums[i], 0) + 1); + currSum += nums[i]; + if (map.size() == k) { + maxSum = Math.max(maxSum, currSum); + } + map.put(nums[startIdx], map.get(nums[startIdx]) - 1); + if (map.get(nums[startIdx]) == 0) { + map.remove(nums[startIdx]); + } + currSum -= nums[startIdx]; + startIdx++; + } + return maxSum; + } +} diff --git a/Medium/Maximum Sum of an Hourglass.java b/Medium/Maximum Sum of an Hourglass.java new file mode 100644 index 00000000..c819295a --- /dev/null +++ b/Medium/Maximum Sum of an Hourglass.java @@ -0,0 +1,22 @@ +class Solution { + + private static final int[][] coordinates = {{0, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, {2, 1}, {2, 2}}; + + public int maxSum(int[][] grid) { + int rows = grid.length; + int cols = grid[0].length; + int highestHourglassSum = 0; + for (int i = 0; i < rows - 2; i++) { + for (int j = 0; j < cols - 2; j++) { + int currSum = 0; + for (int[] coordinate : coordinates) { + int x = i + coordinate[0]; + int y = j + coordinate[1]; + currSum += grid[x][y]; + } + highestHourglassSum = Math.max(highestHourglassSum, currSum); + } + } + return highestHourglassSum; + } +} diff --git a/Medium/Maximum Swap.java b/Medium/Maximum Swap.java new file mode 100644 index 00000000..c12fb12e --- /dev/null +++ b/Medium/Maximum Swap.java @@ -0,0 +1,20 @@ +class Solution { + public int maximumSwap(int num) { + char[] digits = String.valueOf(num).toCharArray(); + int n = digits.length; + int[] maxRightIdx = new int[n]; + maxRightIdx[n - 1] = n - 1; + for (int i = n - 2; i >= 0; i--) { + maxRightIdx[i] = (digits[i] > digits[maxRightIdx[i + 1]]) ? i : maxRightIdx[i + 1]; + } + for (int i = 0; i < n; i++) { + if (digits[i] < digits[maxRightIdx[i]]) { + char temp = digits[i]; + digits[i] = digits[maxRightIdx[i]]; + digits[maxRightIdx[i]] = temp; + return Integer.parseInt(String.valueOf(digits)); + } + } + return num; + } +} diff --git a/Medium/Maximum Total Importance of Roads.java b/Medium/Maximum Total Importance of Roads.java new file mode 100644 index 00000000..52e5eea7 --- /dev/null +++ b/Medium/Maximum Total Importance of Roads.java @@ -0,0 +1,17 @@ +class Solution { + public long maximumImportance(int n, int[][] roads) { + int[] outDegree = new int[n]; + for (int[] road : roads) { + outDegree[road[0]]++; + outDegree[road[1]]++; + } + Arrays.sort(outDegree); + long totalImportance = 0; + long importanceMultiple = 1L; + for (int count : outDegree) { + totalImportance += importanceMultiple * count; + importanceMultiple++; + } + return totalImportance; + } +} diff --git a/Medium/Maximum Twin Sum of a Linked List.java b/Medium/Maximum Twin Sum of a Linked List.java new file mode 100644 index 00000000..5f6b44bd --- /dev/null +++ b/Medium/Maximum Twin Sum of a Linked List.java @@ -0,0 +1,41 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public int pairSum(ListNode head) { + ListNode slow = head; + ListNode fast = head.next; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + } + fast = reverse(slow.next); + slow.next = null; + slow = head; + int maxSum = 0; + for (; slow != null && fast != null; slow = slow.next, fast = fast.next) { + maxSum = Math.max(maxSum, slow.val + fast.val); + } + return maxSum; + } + + private ListNode reverse(ListNode node) { + ListNode curr = node; + ListNode prev = null; + ListNode next = null; + while (curr != null) { + next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + return prev; + } +} diff --git a/Medium/Maximum Value after Insertion.java b/Medium/Maximum Value after Insertion.java new file mode 100644 index 00000000..78213f9b --- /dev/null +++ b/Medium/Maximum Value after Insertion.java @@ -0,0 +1,18 @@ +class Solution { + public String maxValue(String n, int x) { + if (n.charAt(0) == '-') { + for (int i = 1; i < n.length(); i++) { + if (Character.getNumericValue(n.charAt(i)) > x) { + return "-" + n.substring(1, i) + x + n.substring(i); + } + } + } else { + for (int i = 0; i < n.length(); i++) { + if (Character.getNumericValue(n.charAt(i)) < x) { + return n.substring(0, i) + x + n.substring(i); + } + } + } + return n + x; + } +} diff --git a/Medium/Maximum Value at a Given Index in a Bounded Array.java b/Medium/Maximum Value at a Given Index in a Bounded Array.java new file mode 100644 index 00000000..6a1a4966 --- /dev/null +++ b/Medium/Maximum Value at a Given Index in a Bounded Array.java @@ -0,0 +1,30 @@ +class Solution { + public int maxValue(int n, int index, int maxSum) { + int start = 1; + int end = maxSum; + while (start < end) { + int mid = (start + end + 1) / 2; + if (findSum(index, mid, n) <= maxSum) { + start = mid; + } else { + end = mid - 1; + } + } + return start; + } + + private long findSum(int index, int targetIndex, int n) { + long count = 0; + if (targetIndex > index) { + count += (long) (2 * targetIndex - index) * (index + 1) / 2; + } else { + count += (long) (targetIndex + 1) * targetIndex / 2 + index - targetIndex + 1; + } + if (targetIndex >= n - index) { + count += (long) (targetIndex + targetIndex - n + 1 + index) * (n - index) / 2; + } else { + count += (long) (targetIndex + 1) * targetIndex / 2 + n - index - targetIndex; + } + return count - targetIndex; + } +} diff --git a/Medium/Maximum Width Ramp.java b/Medium/Maximum Width Ramp.java index 37eb1862..2463f02b 100644 --- a/Medium/Maximum Width Ramp.java +++ b/Medium/Maximum Width Ramp.java @@ -1,21 +1,18 @@ class Solution { - public int maxWidthRamp(int[] A) { + public int maxWidthRamp(int[] nums) { + int n = nums.length; Stack stack = new Stack<>(); - int ans = 0; - int n = A.length; - - for (int i=0; i A[i]) { - stack.add(i); + for (int i = 0; i < n; i++) { + if (stack.isEmpty() || nums[stack.peek()] > nums[i]) { + stack.push(i); } } - - for (int i=n-1; i>=ans; i--) { - while (!stack.isEmpty() && A[stack.peek()] <= A[i]) { - ans = Math.max(ans, i - stack.pop()); + int result = 0; + for (int i = n - 1; i >= 0; i--) { + while (!stack.isEmpty() && nums[stack.peek()] <= nums[i]) { + result = Math.max(result, i - stack.pop()); } } - - return ans; + return result; } } diff --git a/Medium/Maximum Width of Binary Tree.java b/Medium/Maximum Width of Binary Tree.java index a236cec3..d5edef7e 100644 --- a/Medium/Maximum Width of Binary Tree.java +++ b/Medium/Maximum Width of Binary Tree.java @@ -4,24 +4,40 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public int widthOfBinaryTree(TreeNode root) { - int[] ans = {0}; - Map map = new HashMap<>(); - dfs(root, 0, 0, ans, map); - return ans[0]; - } - - private void dfs(TreeNode root, int depth, int pos, int[] ans, Map map) { - if (root == null) { - return; + public int widthOfBinaryTree(TreeNode root) { + if (root == null) { + return 0; + } + Queue queue = new LinkedList<>(); + queue.add(new NodeColIndex(root, 0)); + int maxWidth = 0; + while (!queue.isEmpty()) { + NodeColIndex head = queue.peek(); + int levelSize = queue.size(); + for (int i = 0; i < levelSize; i++) { + NodeColIndex removed = queue.remove(); + TreeNode node = removed.node; + if (node.left != null) { + queue.add(new NodeColIndex(node.left, 2 * removed.colIdx)); + } + if (node.right != null) { + queue.add(new NodeColIndex(node.right, 2 * removed.colIdx + 1)); + } + maxWidth = Math.max(maxWidth, removed.colIdx - head.colIdx + 1); + } + } + return maxWidth; } - map.putIfAbsent(depth, pos); - ans[0] = Math.max(ans[0], pos - map.get(depth) + 1); - dfs(root.left, depth + 1, 2 * pos, ans, map); - dfs(root.right, depth + 1, 2 * pos + 1, ans, map); - } + + private record NodeColIndex(TreeNode node, int colIdx) {} } diff --git a/Medium/Meeting Rooms II.java b/Medium/Meeting Rooms II.java index e327a24a..ff594c8a 100644 --- a/Medium/Meeting Rooms II.java +++ b/Medium/Meeting Rooms II.java @@ -1,29 +1,15 @@ class Solution { - public int minMeetingRooms(int[][] intervals) { - Arrays.sort(intervals, new Comparator() { - @Override - public int compare(int[] o1, int[] o2) { - int c = o1[0] - o2[0]; - if (c != 0) { - return c; + public int minMeetingRooms(int[][] intervals) { + Arrays.sort(intervals, Comparator.comparingInt((int[] o) -> o[0])); + PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt(a -> a[1])); + int meetingRooms = 0; + for (int[] interval : intervals) { + while (!pq.isEmpty() && pq.peek()[1] <= interval[0]) { + pq.poll(); + } + pq.add(interval); + meetingRooms = Math.max(meetingRooms, pq.size()); } - return o1[1] - o2[1]; - } - }); - PriorityQueue pq = new PriorityQueue<>(new Comparator() { - @Override - public int compare(int[] o1, int[] o2) { - return o1[1] - o2[1]; - } - }); - int maxCount = 0; - for (int i = 0; i < intervals.length; i++) { - while (!pq.isEmpty() && pq.peek()[1] <= intervals[i][0]) { - pq.poll(); - } - pq.add(intervals[i]); - maxCount = Math.max(maxCount, pq.size()); + return meetingRooms; } - return maxCount; - } } diff --git a/Medium/Meeting Scheduler.java b/Medium/Meeting Scheduler.java index 42f7b044..aeb5d8e9 100644 --- a/Medium/Meeting Scheduler.java +++ b/Medium/Meeting Scheduler.java @@ -1,34 +1,22 @@ class Solution { - public List minAvailableDuration(int[][] slots1, int[][] slots2, int duration) { - int idx1 = 0; - int idx2 = 0; - Arrays.sort(slots1, new sortByStartAndEndTime()); - Arrays.sort(slots2, new sortByStartAndEndTime()); - while (idx1 < slots1.length && idx2 < slots2.length) { - int maxStart = Math.max(slots1[idx1][0], slots2[idx2][0]); - int minEnd = Math.min(slots1[idx1][1], slots2[idx2][1]); - if (minEnd - maxStart >= duration) { - return Arrays.asList(maxStart, maxStart + duration); - } - if (slots1[idx1][1] < slots2[idx2][1]) { - idx1++; - } - else { - idx2++; - } + public List minAvailableDuration(int[][] slots1, int[][] slots2, int duration) { + Arrays.sort(slots1, Comparator.comparingInt(o -> o[0])); + Arrays.sort(slots2, Comparator.comparingInt(o -> o[0])); + int idxOne = 0; + int idxTwo = 0; + while (idxOne < slots1.length && idxTwo < slots2.length) { + int maxStart = Math.max(slots1[idxOne][0], slots2[idxTwo][0]); + int minEnd = Math.min(slots1[idxOne][1], slots2[idxTwo][1]); + if (minEnd - maxStart >= duration) { + return List.of(maxStart, maxStart + duration); + } + if (minEnd == slots1[idxOne][1]) { + idxOne++; + } + if (minEnd == slots2[idxTwo][1]) { + idxTwo++; + } + } + return Collections.emptyList(); } - return new ArrayList<>(); - } - - class sortByStartAndEndTime implements Comparator { - - @Override - public int compare(int[] o1, int[] o2) { - int c = o1[0] - o2[0]; - if (c != 0) { - return c; - } - return o1[1] - o2[1]; - } - } } diff --git a/Medium/Merge In Between Linked Lists.java b/Medium/Merge In Between Linked Lists.java new file mode 100644 index 00000000..9f36b5a8 --- /dev/null +++ b/Medium/Merge In Between Linked Lists.java @@ -0,0 +1,30 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode mergeInBetween(ListNode list1, int a, int b, ListNode list2) { + ListNode curr = list1; + for (int i = 1; i < a; i++) { + curr = curr.next; + } + ListNode start = curr; + for (int i = a - 1; i <= b; i++) { + curr = curr.next; + } + ListNode end = curr; + start.next = list2; + curr = list2; + while (curr.next != null) { + curr = curr.next; + } + curr.next = end; + return list1; + } +} diff --git a/Medium/Merge Intervals.java b/Medium/Merge Intervals.java index c770e419..cb0a90cf 100644 --- a/Medium/Merge Intervals.java +++ b/Medium/Merge Intervals.java @@ -1,44 +1,18 @@ class Solution { - public int[][] merge(int[][] intervals) { - Arrays.sort(intervals, new Comparator(){ - public int compare(int[] o1, int[] o2) { - int c = o1[0] - o2[0]; - if (c != 0) { - return c; + public int[][] merge(int[][] intervals) { + Arrays.sort(intervals, Comparator.comparingInt((int[] o) -> o[0]) + .thenComparingInt(o -> o[1])); + int idx = 0; + List result = new ArrayList<>(); + while (idx < intervals.length) { + int start = intervals[idx][0]; + int end = intervals[idx][1]; + idx++; + while (idx < intervals.length && intervals[idx][0] <= end) { + end = Math.max(end, intervals[idx++][1]); + } + result.add(new int[]{start, end}); } - return o1[1] - o2[1]; - } - }); - List intervalList = new ArrayList<>(); - int end = 0; - int n = intervals.length; - int currStart = -1; - int currEnd = -1; - while (end < n) { - if (currStart == -1 && currEnd == -1) { - currStart = intervals[end][0]; - currEnd = intervals[end][1]; - end++; - } - if (end < n) { - if (currEnd >= intervals[end][0]) { - currEnd = Math.max(intervals[end][1], currEnd); - end++; - } - else { - intervalList.add(new int[]{currStart, currEnd}); - currStart = -1; - currEnd = -1; - } - } - if (end == n && currStart != -1 && currEnd != -1) { - intervalList.add(new int[]{currStart, currEnd}); - } - } - int[][] ans = new int[intervalList.size()][2]; - for (int i = 0; i < intervalList.size(); i++) { - ans[i] = intervalList.get(i); + return result.toArray(new int[][]{}); } - return ans; - } } diff --git a/Medium/Merge Nodes in Between Zeros.java b/Medium/Merge Nodes in Between Zeros.java new file mode 100644 index 00000000..e4cb4403 --- /dev/null +++ b/Medium/Merge Nodes in Between Zeros.java @@ -0,0 +1,32 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode mergeNodes(ListNode head) { + ListNode newHead = null; + ListNode prev = null; + ListNode curr = head.next; + while (curr != null) { + prev = curr; + if (newHead == null) { + newHead = prev; + } + int sum = 0; + while (curr != null && curr.val != 0) { + sum += curr.val; + curr = curr.next; + } + prev.val = sum; + curr = curr.next; + prev.next = curr; + } + return newHead; + } +} diff --git a/Medium/Min Cost to Connect All Points.java b/Medium/Min Cost to Connect All Points.java new file mode 100644 index 00000000..168142ca --- /dev/null +++ b/Medium/Min Cost to Connect All Points.java @@ -0,0 +1,64 @@ +class Solution { + public int minCostConnectPoints(int[][] points) { + int n = points.length; + List edges = new ArrayList<>(); + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + int weight = Math.abs(points[i][0] - points[j][0]) + Math.abs(points[i][1] - points[j][1]); + int[] curr = {weight, i, j}; + edges.add(curr); + } + } + Collections.sort(edges, Comparator.comparingInt(a -> a[0])); + UnionFind unionFind = new UnionFind(n); + int minCost = 0; + int edgeUsedCount = 0; + for (int i = 0; i < edges.size() && edgeUsedCount < n - 1; i++) { + int nodeOne = edges.get(i)[1]; + int nodeTwo = edges.get(i)[2]; + int weight = edges.get(i)[0]; + if (unionFind.union(nodeOne, nodeTwo)) { + minCost += weight; + edgeUsedCount++; + } + } + return minCost; + } + + private static class UnionFind { + private final int[] group; + private final int[] rank; + + public UnionFind(int n) { + this.group = new int[n]; + this.rank = new int[n]; + for (int i = 0; i < n; i++) { + this.group[i] = i; + } + } + + public int find(int node) { + if (group[node] != node) { + group[node] = find(group[node]); + } + return group[node]; + } + + public boolean union(int nodeOne, int nodeTwo) { + int groupOne = find(nodeOne); + int groupTwo = find(nodeTwo); + if (groupOne == groupTwo) { + return false; + } + if (rank[groupOne] > rank[groupTwo]) { + group[groupTwo] = groupOne; + } else if (rank[groupOne] < rank[groupTwo]) { + group[groupOne] = groupTwo; + } else { + group[groupOne] = groupTwo; + rank[groupTwo]++; + } + return true; + } + } +} diff --git a/Medium/Min Stack.java b/Medium/Min Stack.java new file mode 100644 index 00000000..70d88780 --- /dev/null +++ b/Medium/Min Stack.java @@ -0,0 +1,33 @@ +class MinStack { + private final Stack stack; + + public MinStack() { + this.stack = new Stack<>(); + } + + public void push(int val) { + int min = stack.isEmpty() ? val : Math.min(val, stack.peek()[1]); + stack.push(new int[]{val, min}); + } + + public void pop() { + stack.pop(); + } + + public int top() { + return stack.peek()[0]; + } + + public int getMin() { + return stack.peek()[1]; + } +} + +/** + * Your MinStack object will be instantiated and called as such: + * MinStack obj = new MinStack(); + * obj.push(val); + * obj.pop(); + * int param_3 = obj.top(); + * int param_4 = obj.getMin(); + */ diff --git a/Medium/Mini Parser.java b/Medium/Mini Parser.java index a900b446..6fba4058 100644 --- a/Medium/Mini Parser.java +++ b/Medium/Mini Parser.java @@ -22,49 +22,45 @@ * public void add(NestedInteger ni); * * // @return the nested list that this NestedInteger holds, if it holds a nested list - * // Return null if this NestedInteger holds a single integer + * // Return empty list if this NestedInteger holds a single integer * public List getList(); * } */ class Solution { public NestedInteger deserialize(String s) { - if (s == null || s.length() == 0) { + if (s.isEmpty()) { return null; } if (s.charAt(0) != '[') { - return new NestedInteger(Integer.valueOf(s)); + return new NestedInteger(Integer.parseInt(s)); } Stack stack = new Stack<>(); NestedInteger curr = null; - int start = 0; - int n = s.length(); - for (int end = 0; end < n; end++) { - char c = s.charAt(end); - if (c == '[') { + int leftIdx = 0; + for (int rightIdx = 0; rightIdx < s.length(); rightIdx++) { + if (s.charAt(rightIdx) == '[') { if (curr != null) { stack.push(curr); } curr = new NestedInteger(); - start = end + 1; - } - else if (c == ']') { - String num = s.substring(start, end); - if (!num.isEmpty()) { - curr.add(new NestedInteger(Integer.valueOf(num))); + leftIdx = rightIdx + 1; + } else if (s.charAt(rightIdx) == ']') { + String number = s.substring(leftIdx, rightIdx); + if (!number.isEmpty()) { + curr.add(new NestedInteger(Integer.parseInt(number))); } if (!stack.isEmpty()) { NestedInteger popped = stack.pop(); popped.add(curr); curr = popped; } - start = end + 1; - } - else if (c == ',') { - if (s.charAt(end - 1) != ']') { - String num = s.substring(start, end); - curr.add(new NestedInteger(Integer.valueOf(num))); + leftIdx = rightIdx + 1; + } else if (s.charAt(rightIdx) == ',') { + if (s.charAt(rightIdx - 1) != ']') { + String number = s.substring(leftIdx, rightIdx); + curr.add(new NestedInteger(Integer.parseInt(number))); } - start = end + 1; + leftIdx = rightIdx + 1; } } return curr; diff --git a/Medium/Minimize Maximum Pair Sum in Array.java b/Medium/Minimize Maximum Pair Sum in Array.java new file mode 100644 index 00000000..4b555253 --- /dev/null +++ b/Medium/Minimize Maximum Pair Sum in Array.java @@ -0,0 +1,13 @@ +class Solution { + public int minPairSum(int[] nums) { + Arrays.sort(nums); + int start = 0; + int end = nums.length - 1; + int maxPairSum = -1; + while (start < end) { + int currSum = nums[start++] + nums[end--]; + maxPairSum = maxPairSum == -1 ? currSum : Math.max(maxPairSum, currSum); + } + return maxPairSum; + } +} diff --git a/Medium/Minimize Maximum of Array.java b/Medium/Minimize Maximum of Array.java new file mode 100644 index 00000000..79d5ee9b --- /dev/null +++ b/Medium/Minimize Maximum of Array.java @@ -0,0 +1,11 @@ +class Solution { + public int minimizeArrayValue(int[] nums) { + long prefixSum = 0L; + long result = 0L; + for (int i = 0; i < nums.length; i++) { + prefixSum += nums[i]; + result = Math.max(result, (prefixSum + i) / (i + 1)); + } + return (int) result; + } +} diff --git a/Medium/Minimize Product Sum of Two Arrays.java b/Medium/Minimize Product Sum of Two Arrays.java new file mode 100644 index 00000000..8302c68e --- /dev/null +++ b/Medium/Minimize Product Sum of Two Arrays.java @@ -0,0 +1,25 @@ +class Solution { + public int minProductSum(int[] nums1, int[] nums2) { + int[] frequencyOne = new int[101]; + int[] frequencyTwo = new int[101]; + for (int i = 0; i < nums1.length; i++) { + frequencyOne[nums1[i]]++; + frequencyTwo[nums2[i]]++; + } + int productSum = 0; + int idxOne = 1; + int idxTwo = 100; + while (idxOne < 101 && idxTwo > 0) { + if (frequencyOne[idxOne] == 0) { + idxOne++; + } else if (frequencyTwo[idxTwo] == 0) { + idxTwo--; + } else { + productSum += idxOne * idxTwo; + frequencyOne[idxOne]--; + frequencyTwo[idxTwo]--; + } + } + return productSum; + } +} diff --git a/Medium/Minimize XOR.java b/Medium/Minimize XOR.java new file mode 100644 index 00000000..cc5e87a3 --- /dev/null +++ b/Medium/Minimize XOR.java @@ -0,0 +1,24 @@ +class Solution { + public int minimizeXor(int num1, int num2) { + int result = 0; + int targetSetBitCount = Integer.bitCount(num2); + int setBitCount = 0; + int currBit = 31; + while (setBitCount < targetSetBitCount) { + if (isSet(num1, currBit) || (targetSetBitCount - setBitCount > currBit)) { + result = setBit(result, currBit); + setBitCount++; + } + currBit--; + } + return result; + } + + private boolean isSet(int x, int bit) { + return (x & (1 << bit)) != 0; + } + + private int setBit(int x, int bit) { + return x | (1 << bit); + } +} diff --git a/Medium/Minimize the Maximum Difference of Pairs.java b/Medium/Minimize the Maximum Difference of Pairs.java new file mode 100644 index 00000000..5ec67591 --- /dev/null +++ b/Medium/Minimize the Maximum Difference of Pairs.java @@ -0,0 +1,30 @@ +class Solution { + public int minimizeMax(int[] nums, int p) { + Arrays.sort(nums); + int n = nums.length; + int start = 0; + int end = nums[n - 1] - nums[0]; + while (start < end) { + int mid = (start + end) / 2; + if (countValidPairs(nums, mid) >= p) { + end = mid; + } else { + start = mid + 1; + } + } + return start; + } + + private static int countValidPairs(int[] nums, int limit) { + int idx = 0; + int count = 0; + while (idx < nums.length - 1) { + if (nums[idx + 1] - nums[idx] <= limit) { + count++; + idx++; + } + idx++; + } + return count; + } +} diff --git a/Medium/Minimized Maximum of Products Distributed to Any Store.java b/Medium/Minimized Maximum of Products Distributed to Any Store.java new file mode 100644 index 00000000..70a46016 --- /dev/null +++ b/Medium/Minimized Maximum of Products Distributed to Any Store.java @@ -0,0 +1,36 @@ +class Solution { + public int minimizedMaximum(int n, int[] quantities) { + int left = 0; + int right = 0; + for (int quantity : quantities) { + right = Math.max(right, quantity); + } + while (left < right) { + int mid = (left + right) / 2; + if (isPossible(n, mid, quantities)) { + right = mid; + } else { + left = mid + 1; + } + } + return left; + } + + private boolean isPossible(int n, int min, int[] quantities) { + int idx = 0; + int remaining = quantities[idx]; + for (int i = 0; i < n; i++) { + if (remaining <= min) { + idx++; + if (idx == quantities.length) { + return true; + } else { + remaining = quantities[idx]; + } + } else { + remaining -= min; + } + } + return false; + } +} diff --git a/Medium/Minimum Add to Make Parentheses Valid.java b/Medium/Minimum Add to Make Parentheses Valid.java index bc78b451..7fcfc88d 100644 --- a/Medium/Minimum Add to Make Parentheses Valid.java +++ b/Medium/Minimum Add to Make Parentheses Valid.java @@ -1,20 +1,14 @@ class Solution { - public int minAddToMakeValid(String S) { - int count = 0; - int open = 0; - for (char c : S.toCharArray()) { - if (c == '(') { - open++; - } - else { - if (open != 0) { - open--; + public int minAddToMakeValid(String s) { + int open = 0; + int count = 0; + for (char c : s.toCharArray()) { + open += c == '(' ? 1 : -1; + if (open < 0) { + count += Math.abs(open); + open = 0; + } } - else { - count++; - } - } + return count + open; } - return count + open; - } } diff --git a/Medium/Minimum Amount of Time to Collect Garbage.java b/Medium/Minimum Amount of Time to Collect Garbage.java new file mode 100644 index 00000000..ace2125d --- /dev/null +++ b/Medium/Minimum Amount of Time to Collect Garbage.java @@ -0,0 +1,25 @@ +class Solution { + public int garbageCollection(String[] garbage, int[] travel) { + Map lastIdx = new HashMap<>(); + for (int i = garbage.length - 1; i >= 0; i--) { + if (garbage[i].indexOf('M') != -1) { + lastIdx.putIfAbsent('M', i); + } + if (garbage[i].indexOf('G') != -1) { + lastIdx.putIfAbsent('G', i); + } + if (garbage[i].indexOf('P') != -1) { + lastIdx.putIfAbsent('P', i); + } + } + int totalTime = 0; + for (int i = 0; i < garbage.length; i++) { + int travelTime = i == 0 ? 0 : travel[i - 1]; + totalTime += garbage[i].length(); + totalTime += lastIdx.getOrDefault('P', -1) >= i ? travelTime : 0; + totalTime += lastIdx.getOrDefault('M', -1) >= i ? travelTime : 0; + totalTime += lastIdx.getOrDefault('G', -1) >= i ? travelTime : 0; + } + return totalTime; + } +} diff --git a/Medium/Minimum Average Difference.java b/Medium/Minimum Average Difference.java new file mode 100644 index 00000000..995bcd11 --- /dev/null +++ b/Medium/Minimum Average Difference.java @@ -0,0 +1,23 @@ +class Solution { + public int minimumAverageDifference(int[] nums) { + int n = nums.length; + long[] prefixSumArray = new long[n]; + long currSum = 0; + for (int i = 0; i < n; i++) { + currSum += nums[i]; + prefixSumArray[i] = currSum; + } + long minDifference = Integer.MAX_VALUE; + int minDifferenceIdx = -1; + for (int i = 0; i < n; i++) { + long leftAverage = prefixSumArray[i] / (i + 1); + long rightAverage = (i == n - 1) ? 0 : (prefixSumArray[n - 1] - prefixSumArray[i]) / (n - 1 - i); + long absoluteDiff = Math.abs(leftAverage - rightAverage); + if (minDifference > absoluteDiff) { + minDifference = absoluteDiff; + minDifferenceIdx = i; + } + } + return minDifferenceIdx; + } +} diff --git a/Medium/Minimum Consecutive Cards to Pick Up.java b/Medium/Minimum Consecutive Cards to Pick Up.java new file mode 100644 index 00000000..147cc54e --- /dev/null +++ b/Medium/Minimum Consecutive Cards to Pick Up.java @@ -0,0 +1,13 @@ +class Solution { + public int minimumCardPickup(int[] cards) { + int minCount = Integer.MAX_VALUE; + Map map = new HashMap<>(); + for (int i = 0; i < cards.length; i++) { + if (map.containsKey(cards[i])) { + minCount = Math.min(minCount, i - map.get(cards[i]) + 1); + } + map.put(cards[i], i); + } + return minCount == Integer.MAX_VALUE ? -1 : minCount; + } +} diff --git a/Medium/Minimum Cost For Tickets.java b/Medium/Minimum Cost For Tickets.java new file mode 100644 index 00000000..8867660b --- /dev/null +++ b/Medium/Minimum Cost For Tickets.java @@ -0,0 +1,29 @@ +class Solution { + public int mincostTickets(int[] days, int[] costs) { + Set daySet = new HashSet<>(); + for (int day : days) { + daySet.add(day); + } + int[] dp = new int[days[days.length - 1]]; + return helper(days[days.length - 1], daySet, costs, dp); + } + + private int helper(int currDay, Set daySet, int[] costs, int[] dp) { + if (currDay <= 0) { + return 0; + } + if (dp[currDay - 1] != 0) { + return dp[currDay - 1]; + } + int result = 0; + if (daySet.contains(currDay)) { + int one = helper(currDay - 1, daySet, costs, dp) + costs[0]; + int seven = helper(currDay - 7, daySet, costs, dp) + costs[1]; + int thirty = helper(currDay - 30, daySet, costs, dp) + costs[2]; + result = Math.min(one, Math.min(seven, thirty)); + } else { + result = helper(currDay - 1, daySet, costs, dp); + } + return dp[currDay - 1] = result; + } +} diff --git a/Medium/Minimum Deletions to Make Array Beautiful.java b/Medium/Minimum Deletions to Make Array Beautiful.java new file mode 100644 index 00000000..8567e813 --- /dev/null +++ b/Medium/Minimum Deletions to Make Array Beautiful.java @@ -0,0 +1,14 @@ +class Solution { + public int minDeletion(int[] nums) { + int numOfDeletions = 0; + int prevNum = -1; + for (int num : nums) { + if (num == prevNum) { + numOfDeletions++; + } else { + prevNum = prevNum == -1 ? num : -1; + } + } + return prevNum == -1 ? numOfDeletions : numOfDeletions + 1; + } +} diff --git a/Medium/Minimum Deletions to Make Character Frequencies Unique.java b/Medium/Minimum Deletions to Make Character Frequencies Unique.java new file mode 100644 index 00000000..2d57dc68 --- /dev/null +++ b/Medium/Minimum Deletions to Make Character Frequencies Unique.java @@ -0,0 +1,25 @@ +class Solution { + public int minDeletions(String s) { + int[] frequency = new int[26]; + for (char c : s.toCharArray()) { + frequency[c - 'a']++; + } + Arrays.sort(frequency); + int numOfDeletions = 0; + int expectedFrequency = frequency[25]; + for (int i = 25; i >= 0; i--) { + if (frequency[i] == 0) { + break; + } + if (frequency[i] > expectedFrequency) { + numOfDeletions += frequency[i] - expectedFrequency; + } else { + expectedFrequency = frequency[i]; + } + if (expectedFrequency > 0) { + expectedFrequency--; + } + } + return numOfDeletions; + } +} diff --git a/Medium/Minimum Difference Between Largest and Smallest Value in Three Moves.java b/Medium/Minimum Difference Between Largest and Smallest Value in Three Moves.java new file mode 100644 index 00000000..2722191a --- /dev/null +++ b/Medium/Minimum Difference Between Largest and Smallest Value in Three Moves.java @@ -0,0 +1,16 @@ +class Solution { + public int minDifference(int[] nums) { + int n = nums.length; + if (n <= 4) { + return 0; + } + Arrays.sort(nums); + int minDiff = Integer.MAX_VALUE; + int left = 0; + int right = n - 4; + while (left < 4) { + minDiff = Math.min(minDiff, nums[right++] - nums[left++]); + } + return minDiff; + } +} diff --git a/Medium/Minimum Falling Path Sum.java b/Medium/Minimum Falling Path Sum.java new file mode 100644 index 00000000..255081b9 --- /dev/null +++ b/Medium/Minimum Falling Path Sum.java @@ -0,0 +1,33 @@ +class Solution { + private static final int[][] DIRS = {{1, -1}, {1, 0}, {1, 1}}; + + public int minFallingPathSum(int[][] matrix) { + int rows = matrix.length; + int cols = matrix[0].length; + Integer[][] dp = new Integer[rows + 1][cols + 1]; + int result = Integer.MAX_VALUE; + for (int i = 0; i < cols; i++) { + result = Math.min(result, recurse(matrix, 0, i, rows, cols, dp)); + } + return result; + } + + private int recurse(int[][] matrix, int row, int col, int rows, int cols, Integer[][] dp) { + if (row == rows - 1) { + return matrix[row][col]; + } + if (dp[row][col] != null) { + return dp[row][col]; + } + int result = Integer.MAX_VALUE; + for (int[] dir : DIRS) { + int newRow = row + dir[0]; + int newCol = col + dir[1]; + if (newRow < 0 || newCol < 0 || newRow >= rows || newCol >= cols) { + continue; + } + result = Math.min(result, matrix[row][col] + recurse(matrix, newRow, newCol, rows, cols, dp)); + } + return dp[row][col] = result; + } +} diff --git a/Medium/Minimum Flips to Make a OR b Equal to c.java b/Medium/Minimum Flips to Make a OR b Equal to c.java new file mode 100644 index 00000000..91963256 --- /dev/null +++ b/Medium/Minimum Flips to Make a OR b Equal to c.java @@ -0,0 +1,5 @@ +class Solution { + public int minFlips(int a, int b, int c) { + return Integer.bitCount((a | b) ^ c) + Integer.bitCount(a & b & ((a | b) ^ c)); + } +} diff --git a/Medium/Minimum Fuel Cost to Report to the Capital.java b/Medium/Minimum Fuel Cost to Report to the Capital.java new file mode 100644 index 00000000..ee48239f --- /dev/null +++ b/Medium/Minimum Fuel Cost to Report to the Capital.java @@ -0,0 +1,28 @@ +class Solution { + public long minimumFuelCost(int[][] roads, int seats) { + Map> graph = new HashMap<>(); + for (int[] road : roads) { + graph.computeIfAbsent(road[0], k -> new ArrayList<>()).add(road[1]); + graph.computeIfAbsent(road[1], k -> new ArrayList<>()).add(road[0]); + } + long[] fuel = {0l}; + dfs(0, -1, graph, seats, fuel); + return fuel[0]; + } + + private long dfs(int node, int parent, Map> graph, int seats, long[] fuel) { + int representativeCount = 1; + if (!graph.containsKey(node)) { + return representativeCount; + } + for (int child : graph.get(node)) { + if (child != parent) { + representativeCount += dfs(child, node, graph, seats, fuel); + } + } + if (node != 0) { + fuel[0] += Math.ceil((double) representativeCount / seats); + } + return representativeCount; + } +} diff --git a/Medium/Minimum Health to Beat Game.java b/Medium/Minimum Health to Beat Game.java new file mode 100644 index 00000000..9b93099e --- /dev/null +++ b/Medium/Minimum Health to Beat Game.java @@ -0,0 +1,11 @@ +class Solution { + public long minimumHealth(int[] damage, int armor) { + int maxDamage = 0; + long totalDamage = 0; + for (int d : damage) { + totalDamage += d; + maxDamage = Math.max(maxDamage, d); + } + return totalDamage - Math.min(armor, maxDamage) + 1; + } +} diff --git a/Medium/Minimum Height Trees.java b/Medium/Minimum Height Trees.java index 8bf0e21f..a92f7494 100644 --- a/Medium/Minimum Height Trees.java +++ b/Medium/Minimum Height Trees.java @@ -4,7 +4,7 @@ public List findMinHeightTrees(int n, int[][] edges) { return Collections.singletonList(0); } Map> map = new HashMap<>(); - for (int[] edge: edges) { + for (int[] edge : edges) { map.computeIfAbsent(edge[0], k -> new HashSet<>()).add(edge[1]); map.computeIfAbsent(edge[1], k -> new HashSet<>()).add(edge[0]); } @@ -19,7 +19,8 @@ public List findMinHeightTrees(int n, int[][] edges) { int size = leaves.size(); count -= size; List newLeaves = new ArrayList<>(); - for (int leaf : leaves) { + for (int i = 0; i < size; i++) { + int leaf = leaves.get(i); for (int toRemove : map.getOrDefault(leaf, new HashSet<>())) { map.get(toRemove).remove(leaf); if (map.get(toRemove).size() == 1) { diff --git a/Medium/Minimum Increment to Make Array Unique.java b/Medium/Minimum Increment to Make Array Unique.java new file mode 100644 index 00000000..7be5a583 --- /dev/null +++ b/Medium/Minimum Increment to Make Array Unique.java @@ -0,0 +1,13 @@ +class Solution { + public int minIncrementForUnique(int[] nums) { + Arrays.sort(nums); + int increments = 0; + for (int i = 1; i < nums.length; i++) { + if (nums[i] <= nums[i - 1]) { + increments += nums[i - 1] + 1 - nums[i]; + nums[i] = nums[i - 1] + 1; + } + } + return increments; + } +} diff --git a/Medium/Minimum Knight Moves.java b/Medium/Minimum Knight Moves.java index 94d27fbe..35759df8 100644 --- a/Medium/Minimum Knight Moves.java +++ b/Medium/Minimum Knight Moves.java @@ -1,38 +1,30 @@ class Solution { - public final int[][] DIRS = {{2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}, {1, -2}, {2, -1}}; - public int minKnightMoves(int x, int y) { - int currX = 0; - int currY = 0; - int targetX = Math.abs(x); - int targetY = Math.abs(y); - Set visited = new HashSet<>(); - Queue queue = new LinkedList<>(); - int numOfSteps = 0; - visited.add(currX + "|" + currY); - queue.add(new int[]{currX, currY}); - while (!queue.isEmpty()) { - int size = queue.size(); - boolean found = false; - while (size-- > 0) { - int[] removed = queue.remove(); - if (removed[0] == targetX && removed[1] == targetY) { - found = true; - break; + + private static final int[][] MOVES = {{1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}}; + + public int minKnightMoves(int x, int y) { + boolean[][] visited = new boolean[607][607]; + Queue queue = new LinkedList<>(); + queue.add(new int[]{0, 0}); + int steps = 0; + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + int[] removed = queue.remove(); + if (removed[0] == x && removed[1] == y) { + return steps; + } + for (int[] move : MOVES) { + int newX = removed[0] + move[0]; + int newY = removed[1] + move[1]; + if (!visited[newX + 302][newY + 302]) { + visited[newX + 302][newY + 302] = true; + queue.add(new int[]{newX, newY}); + } + } + } + steps++; } - for (int[] dir : DIRS) { - int newX = removed[0] + dir[0]; - int newY = removed[1] + dir[1]; - if (!visited.contains(newX + "|" + newY) && newX >= -1 && newY >= -1) { - visited.add(newX + "|" + newY); - queue.add(new int[]{newX, newY}); - } - } - } - if (found) { - break; - } - numOfSteps++; + return steps; } - return numOfSteps; - } } diff --git a/Medium/Minimum Length of String After Deleting Similar Ends.java b/Medium/Minimum Length of String After Deleting Similar Ends.java new file mode 100644 index 00000000..bc1c6c89 --- /dev/null +++ b/Medium/Minimum Length of String After Deleting Similar Ends.java @@ -0,0 +1,17 @@ +class Solution { + public int minimumLength(String s) { + int start = 0; + int end = s.length() - 1; + while (start < end && s.charAt(start) == s.charAt(end)) { + char startChar = s.charAt(start); + char endChar = s.charAt(end); + while (start <= end && s.charAt(start) == startChar) { + start++; + } + while (end > start && s.charAt(end) == endChar) { + end--; + } + } + return end - start + 1; + } +} diff --git a/Medium/Minimum Levels to Gain More Points.java b/Medium/Minimum Levels to Gain More Points.java new file mode 100644 index 00000000..c7fd7222 --- /dev/null +++ b/Medium/Minimum Levels to Gain More Points.java @@ -0,0 +1,17 @@ +class Solution { + public int minimumLevels(int[] possible) { + int n = possible.length; + int totalScore = 0; + for (int i = n - 1; i >= 0; i--) { + totalScore += possible[i] == 1 ? 1 : -1; + } + int score = 0; + for (int i = 0; i < n - 1; i++) { + score += possible[i] == 1 ? 1 : -1; + if (score > totalScore - score) { + return i + 1; + } + } + return -1; + } +} diff --git a/Medium/Minimum Moves to Equal Array Elements II.java b/Medium/Minimum Moves to Equal Array Elements II.java index 921078ed..1a0ac919 100644 --- a/Medium/Minimum Moves to Equal Array Elements II.java +++ b/Medium/Minimum Moves to Equal Array Elements II.java @@ -1,17 +1,12 @@ class Solution { - public int minMoves2(int[] nums) { - int i = 0; - int j = nums.length-1; - int c = 0; - - Arrays.sort(nums); - - while (i < j) { - c += nums[j] - nums[i]; - i++; - j--; - } - - return c; + public int minMoves2(int[] nums) { + Arrays.sort(nums); + int sum = 0; + int start = 0; + int end = nums.length - 1; + while (start < end) { + sum += nums[end--] - nums[start++]; } + return sum; + } } diff --git a/Medium/Minimum Moves to Equal Array Elements.java b/Medium/Minimum Moves to Equal Array Elements.java new file mode 100644 index 00000000..78d30c6f --- /dev/null +++ b/Medium/Minimum Moves to Equal Array Elements.java @@ -0,0 +1,12 @@ +class Solution { + public int minMoves(int[] nums) { + Arrays.sort(nums); + int moves = 0; + for (int i = 1; i < nums.length; i++) { + int diff = (moves + nums[i]) - nums[i - 1]; + nums[i] += moves; + moves += diff; + } + return moves; + } +} diff --git a/Medium/Minimum Moves to Reach Target Score.java b/Medium/Minimum Moves to Reach Target Score.java new file mode 100644 index 00000000..c9bfdfc0 --- /dev/null +++ b/Medium/Minimum Moves to Reach Target Score.java @@ -0,0 +1,15 @@ +class Solution { + public int minMoves(int target, int maxDoubles) { + int numOfSteps = 0; + while (target > 0 && maxDoubles > 0) { + if (target % 2 == 0) { + maxDoubles--; + target /= 2; + } else { + target--; + } + numOfSteps++; + } + return numOfSteps + target - 1; + } +} diff --git a/Medium/Minimum Number of Arrows to Burst Balloons.java b/Medium/Minimum Number of Arrows to Burst Balloons.java index b801e00b..a00d9274 100644 --- a/Medium/Minimum Number of Arrows to Burst Balloons.java +++ b/Medium/Minimum Number of Arrows to Burst Balloons.java @@ -1,26 +1,14 @@ class Solution { public int findMinArrowShots(int[][] points) { - if (points.length == 0) { - return 0; - } - Arrays.sort(points, new Comparator(){ - public int compare(int[] p1, int[] p2) { - int c = p1[0] - p2[0]; - if (c != 0) { - return c; - } - return p1[1] - p2[1]; - } - }); - int end = points[0][1]; - int count = 1; - for (int i = 1; i < points.length; i++) { - if (points[i][0] <= end) { - end = Math.min(end, points[i][1]); - continue; + Arrays.sort(points, Comparator.comparingInt((int[] o) -> o[1])); + int count = 0; + int idx = 0; + while (idx < points.length) { + int currEnd = points[idx][1]; + while (idx < points.length && points[idx][0] <= currEnd) { + idx++; } count++; - end = points[i][1]; } return count; } diff --git a/Medium/Minimum Number of Days to Make m Bouquets.java b/Medium/Minimum Number of Days to Make m Bouquets.java new file mode 100644 index 00000000..83578712 --- /dev/null +++ b/Medium/Minimum Number of Days to Make m Bouquets.java @@ -0,0 +1,37 @@ +class Solution { + public int minDays(int[] bloomDay, int m, int k) { + int left = 0; + int right = 0; + for (int day : bloomDay) { + right = Math.max(right, day); + } + int days = -1; + while (left <= right) { + int mid = (left + right) / 2; + if (numberOfBouquet(bloomDay, mid, k) >= m) { + days = mid; + right = mid - 1; + } else { + left = mid + 1; + } + } + return days; + } + + private int numberOfBouquet(int[] bloomDay, int mid, int k) { + int bouquetCount = 0; + int count = 0; + for (int i = 0; i < bloomDay.length; i++) { + if (bloomDay[i] <= mid) { + count++; + } else { + count = 0; + } + if (count == k) { + bouquetCount++; + count = 0; + } + } + return bouquetCount; + } +} diff --git a/Medium/Minimum Number of Operations to Make Array Empty.java b/Medium/Minimum Number of Operations to Make Array Empty.java new file mode 100644 index 00000000..69754a8d --- /dev/null +++ b/Medium/Minimum Number of Operations to Make Array Empty.java @@ -0,0 +1,16 @@ +class Solution { + public int minOperations(int[] nums) { + Map map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + int operations = 0; + for (Integer value : map.values()) { + if (value == 1) { + return -1; + } + operations += value / 3 + (value % 3 == 0 ? 0 : 1); + } + return operations; + } +} diff --git a/Medium/Minimum Number of Pushes to Type Word II.java b/Medium/Minimum Number of Pushes to Type Word II.java new file mode 100644 index 00000000..71ec90f6 --- /dev/null +++ b/Medium/Minimum Number of Pushes to Type Word II.java @@ -0,0 +1,23 @@ +class Solution { + public int minimumPushes(String word) { + Map map = new HashMap<>(); + for (char c : word.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); + } + PriorityQueue pq = new PriorityQueue<>((a, b) -> map.get(b).compareTo(map.get(a))); + pq.addAll(map.keySet()); + int count = 0; + int typeMultiple = 1; + int counter = 0; + while (!pq.isEmpty()) { + char removed = pq.poll(); + count += typeMultiple * map.get(removed); + counter++; + if (counter == 8) { + counter = 0; + typeMultiple++; + } + } + return count; + } +} diff --git a/Medium/Minimum Number of Steps to Make Two Strings Anagram II.java b/Medium/Minimum Number of Steps to Make Two Strings Anagram II.java new file mode 100644 index 00000000..0c72d548 --- /dev/null +++ b/Medium/Minimum Number of Steps to Make Two Strings Anagram II.java @@ -0,0 +1,16 @@ +class Solution { + public int minSteps(String s, String t) { + int[] frequency = new int[26]; + for (char c : s.toCharArray()) { + frequency[c - 'a']++; + } + for (char c : t.toCharArray()) { + frequency[c - 'a']--; + } + int totalSteps = 0; + for (int i = 0; i < 26; i++) { + totalSteps += Math.abs(frequency[i]); + } + return totalSteps; + } +} diff --git a/Medium/Minimum Number of Steps to Make Two Strings Anagram.java b/Medium/Minimum Number of Steps to Make Two Strings Anagram.java new file mode 100644 index 00000000..55139382 --- /dev/null +++ b/Medium/Minimum Number of Steps to Make Two Strings Anagram.java @@ -0,0 +1,16 @@ +class Solution { + public int minSteps(String s, String t) { + int[] frequency = new int[26]; + for (int i = 0; i < s.length(); i++) { + frequency[s.charAt(i) - 'a']++; + frequency[t.charAt(i) - 'a']--; + } + int steps = 0; + for (int i = 0; i < 26; i++) { + if (frequency[i] > 0) { + steps += frequency[i]; + } + } + return steps; + } +} diff --git a/Medium/Minimum Number of Swaps to Make the String Balanced.java b/Medium/Minimum Number of Swaps to Make the String Balanced.java new file mode 100644 index 00000000..79935f13 --- /dev/null +++ b/Medium/Minimum Number of Swaps to Make the String Balanced.java @@ -0,0 +1,24 @@ +class Solution { + public int minSwaps(String s) { + char[] chars = s.toCharArray(); + Stack openBrackets = new Stack<>(); + for (int i = 0; i < chars.length; i++) { + if (chars[i] == '[') { + openBrackets.push(i); + } + } + int open = 0; + int swaps = 0; + for (int i = 0; i < chars.length; i++) { + open += chars[i] == '[' ? 1 : -1; + if (open < 0) { + swaps++; + int endIdx = openBrackets.pop(); + chars[endIdx] = ']'; + chars[i] = '['; + open += 2; + } + } + return swaps; + } +} diff --git a/Medium/Minimum Number of Vertices to Reach All Nodes.java b/Medium/Minimum Number of Vertices to Reach All Nodes.java index 6c0688b6..6459877d 100644 --- a/Medium/Minimum Number of Vertices to Reach All Nodes.java +++ b/Medium/Minimum Number of Vertices to Reach All Nodes.java @@ -1,15 +1,15 @@ class Solution { - public List findSmallestSetOfVertices(int n, List> edges) { - int[] indegree = new int[n]; - for (List edge : edges) { - indegree[edge.get(1)]++; + public List findSmallestSetOfVertices(int n, List> edges) { + int[] indegree = new int[n]; + for (List edge : edges) { + indegree[edge.get(1)]++; + } + List zeroIndegree = new ArrayList<>(); + for (int i = 0; i < n; i++) { + if (indegree[i] == 0) { + zeroIndegree.add(i); + } + } + return zeroIndegree; } - List ans = new ArrayList<>(); - for (int i = 0; i < n; i++) { - if (indegree[i] == 0) { - ans.add(i); - } - } - return ans; - } } diff --git a/Medium/Minimum Operations to Exceed Threshold Value II.java b/Medium/Minimum Operations to Exceed Threshold Value II.java new file mode 100644 index 00000000..9a6c2b09 --- /dev/null +++ b/Medium/Minimum Operations to Exceed Threshold Value II.java @@ -0,0 +1,17 @@ +class Solution { + public int minOperations(int[] nums, int k) { + PriorityQueue pq = new PriorityQueue<>(); + for (int num : nums) { + pq.add((long) num); + } + int operations = 0; + while (pq.peek() < k) { + long smallest = pq.poll(); + long secondSmallest = pq.poll(); + long newValue = Math.min(smallest, secondSmallest) * 2 + Math.max(smallest, secondSmallest); + pq.add(newValue); + operations++; + } + return operations; + } +} diff --git a/Medium/Minimum Operations to Make Binary Array Elements Equal to One I.java b/Medium/Minimum Operations to Make Binary Array Elements Equal to One I.java new file mode 100644 index 00000000..4b5b20a1 --- /dev/null +++ b/Medium/Minimum Operations to Make Binary Array Elements Equal to One I.java @@ -0,0 +1,19 @@ +class Solution { + public int minOperations(int[] nums) { + int count = 0; + for (int i = 0; i <= nums.length - 3; i++) { + if (nums[i] == 0) { + nums[i] = nums[i] == 0 ? 1 : 0; + nums[i + 1] = nums[i + 1] == 0 ? 1 : 0; + nums[i + 2] = nums[i + 2] == 0 ? 1 : 0; + count++; + } + } + for (int i = nums.length - 3; i < nums.length; i++) { + if (nums[i] == 0) { + return -1; + } + } + return count; + } +} diff --git a/Medium/Minimum Operations to Make a Special Number.java b/Medium/Minimum Operations to Make a Special Number.java new file mode 100644 index 00000000..20f250fc --- /dev/null +++ b/Medium/Minimum Operations to Make a Special Number.java @@ -0,0 +1,25 @@ +class Solution { + + private final int NOT_FOUND_VALUE = 100_000; + + public int minimumOperations(String num) { + Integer[][] dp = new Integer[100][25]; + return helper(num, 0, 0, dp); + } + + private int helper(String num, int idx, int mod, Integer[][] dp) { + if (idx == num.length()) { + if (mod == 0) { + return 0; + } + return NOT_FOUND_VALUE; + } + if (dp[idx][mod] != null) { + return dp[idx][mod]; + } + int take = helper(num, idx + 1, (mod * 10 + (num.charAt(idx) - '0')) % 25, dp); + int remove = 1 + helper(num, idx + 1, mod, dp); + dp[idx][mod] = Math.min(take, remove); + return dp[idx][mod]; + } +} diff --git a/Medium/Minimum Operations to Reduce X to Zero.java b/Medium/Minimum Operations to Reduce X to Zero.java new file mode 100644 index 00000000..f2f2a99b --- /dev/null +++ b/Medium/Minimum Operations to Reduce X to Zero.java @@ -0,0 +1,22 @@ +class Solution { + public int minOperations(int[] nums, int x) { + int sum = 0; + for (int num : nums) { + sum += num; + } + int max = -1; + int left = 0; + int curr = 0; + int n = nums.length; + for (int right = 0; right < n; right++) { + curr += nums[right]; + while (curr > sum - x && left <= right) { + curr -= nums[left++]; + } + if (curr == sum - x) { + max = Math.max(max, right - left + 1); + } + } + return max != -1 ? n - max : -1; + } +} diff --git a/Medium/Minimum Path Sum.java b/Medium/Minimum Path Sum.java index 5a19e3ac..0565b7b0 100644 --- a/Medium/Minimum Path Sum.java +++ b/Medium/Minimum Path Sum.java @@ -1,22 +1,18 @@ class Solution { - public static int minPathSum(int[][] grid) { - int m = grid.length; - int n = grid[0].length; - - for (int i=0; i 0 && j > 0) { + dp[i][j] += Math.min(dp[i - 1][j], dp[i][j - 1]); + } else if (i > 0) { + dp[i][j] += dp[i - 1][j]; + } else if (j > 0) { + dp[i][j] += dp[i][j - 1]; } } } - - return grid[m-1][n-1]; + return dp[grid.length - 1][grid[0].length - 1]; } } diff --git a/Medium/Minimum Penalty for a Shop.java b/Medium/Minimum Penalty for a Shop.java new file mode 100644 index 00000000..e5c5eaa9 --- /dev/null +++ b/Medium/Minimum Penalty for a Shop.java @@ -0,0 +1,16 @@ +class Solution { + public int bestClosingTime(String customers) { + int n = customers.length(); + int minPenalty = 0; + int currPenalty = 0; + int minPenaltyHour = 0; + for (int i = 0; i < n; i++) { + currPenalty += customers.charAt(i) == 'Y' ? -1 : 1; + if (currPenalty < minPenalty) { + minPenaltyHour = i + 1; + minPenalty = currPenalty; + } + } + return minPenaltyHour; + } +} diff --git a/Medium/Minimum Processing Time.java b/Medium/Minimum Processing Time.java new file mode 100644 index 00000000..ec9b75e6 --- /dev/null +++ b/Medium/Minimum Processing Time.java @@ -0,0 +1,18 @@ +class Solution { + public int minProcessingTime(List processorTime, List tasks) { + PriorityQueue taskQueue = new PriorityQueue<>(); + PriorityQueue processorQueue = new PriorityQueue<>((a, b) -> b - a); + taskQueue.addAll(tasks); + processorQueue.addAll(processorTime); + int totalTime = Integer.MIN_VALUE; + while (!processorQueue.isEmpty()) { + int startTime = processorQueue.remove(); + int currTime = Integer.MIN_VALUE; + for (int i = 0; i < 4; i++) { + currTime = Math.max(currTime, startTime + taskQueue.remove()); + } + totalTime = Math.max(totalTime, currTime); + } + return totalTime; + } +} diff --git a/Medium/Minimum Remove to Make Valid Parentheses.java b/Medium/Minimum Remove to Make Valid Parentheses.java index bc1739e4..7d5be988 100644 --- a/Medium/Minimum Remove to Make Valid Parentheses.java +++ b/Medium/Minimum Remove to Make Valid Parentheses.java @@ -1,29 +1,28 @@ class Solution { - public String minRemoveToMakeValid(String s) { - Stack stack = new Stack<>(); - char[] chars = s.toCharArray(); - for (int i = 0; i < chars.length; i++) { - if (chars[i] == '(') { - stack.push(i); - } - else if (chars[i] == ')') { - if (stack.isEmpty()) { - chars[i] = '-'; + public String minRemoveToMakeValid(String s) { + char[] letters = s.toCharArray(); + Stack stack = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '(') { + stack.push(i); + } else if (c == ')') { + if (stack.isEmpty()) { + letters[i] = '-'; + } else { + stack.pop(); + } + } } - else { - stack.pop(); + while (!stack.isEmpty()) { + letters[stack.pop()] = '-'; } - } - } - while (!stack.isEmpty()) { - chars[stack.pop()] = '-'; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < chars.length; i++) { - if (chars[i] != '-') { - sb.append(chars[i]); - } + StringBuilder sb = new StringBuilder(); + for (char c : letters) { + if (c != '-') { + sb.append(c); + } + } + return sb.toString(); } - return sb.toString(); - } } diff --git a/Medium/Minimum Rounds to Complete All Tasks.java b/Medium/Minimum Rounds to Complete All Tasks.java new file mode 100644 index 00000000..309810a0 --- /dev/null +++ b/Medium/Minimum Rounds to Complete All Tasks.java @@ -0,0 +1,22 @@ +class Solution { + public int minimumRounds(int[] tasks) { + Map frequencyMap = Arrays.stream(tasks) + .boxed() + .collect(Collectors.groupingBy( + Function.identity(), + HashMap::new, + Collectors.counting())); + int rounds = 0; + for (Long occurrences : frequencyMap.values()) { + if (occurrences == 1) { + return -1; + } + if (occurrences % 3 == 0) { + rounds += (int) (occurrences / 3); + } else { + rounds += (int) (occurrences / 3 + 1); + } + } + return rounds; + } +} diff --git a/Medium/Minimum Score of a Path Between Two Cities.java b/Medium/Minimum Score of a Path Between Two Cities.java new file mode 100644 index 00000000..28b7ed1b --- /dev/null +++ b/Medium/Minimum Score of a Path Between Two Cities.java @@ -0,0 +1,31 @@ +class Solution { + public int minScore(int n, int[][] roads) { + Map>> graph = new HashMap<>(); + for (int[] road : roads) { + graph.computeIfAbsent(road[0], k -> new ArrayList<>()) + .add(List.of(road[1], road[2])); + graph.computeIfAbsent(road[1], k -> new ArrayList<>()) + .add(List.of(road[0], road[2])); + } + return bfs(n, graph); + } + + private int bfs(int n , Map>> graph) { + boolean[] visited = new boolean[n + 1]; + Queue queue = new LinkedList<>(); + int result = Integer.MAX_VALUE; + queue.add(1); + visited[1] = true; + while (!queue.isEmpty()) { + int node = queue.remove(); + for (List edge : graph.getOrDefault(node, new ArrayList<>())) { + result = Math.min(result, edge.get(1)); + if (!visited[edge.get(0)]) { + visited[edge.get(0)] = true; + queue.add(edge.get(0)); + } + } + } + return result; + } +} diff --git a/Medium/Minimum Size Subarray Sum.java b/Medium/Minimum Size Subarray Sum.java index 4d41780e..5bafe959 100644 --- a/Medium/Minimum Size Subarray Sum.java +++ b/Medium/Minimum Size Subarray Sum.java @@ -1,30 +1,18 @@ class Solution { - public int minSubArrayLen(int s, int[] nums) { - int sum = 0; - int slow = 0; - int fast = 0; - int n = nums.length; - int minLen = Integer.MAX_VALUE; - - while (fast < n) { - sum += nums[fast]; - - if (sum >= s) { - while (slow <= fast) { - minLen = Math.min(minLen, fast - slow + 1); - if (sum - nums[slow] >= s) { - sum -= nums[slow]; - slow++; - } - else { - break; - } - } + public int minSubArrayLen(int target, int[] nums) { + int start = 0; + int end = 0; + int currSum = 0; + int minLength = Integer.MAX_VALUE; + while (end < nums.length) { + currSum += nums[end++]; + while (start < end && currSum - nums[start] >= target) { + currSum -= nums[start++]; + } + if (currSum >= target) { + minLength = Math.min(minLength, end - start); } - - fast++; } - - return minLen == Integer.MAX_VALUE ? 0 : minLen; + return minLength == Integer.MAX_VALUE ? 0 : minLength; } } diff --git a/Medium/Minimum Speed to Arrive on Time.java b/Medium/Minimum Speed to Arrive on Time.java new file mode 100644 index 00000000..c5751902 --- /dev/null +++ b/Medium/Minimum Speed to Arrive on Time.java @@ -0,0 +1,26 @@ +class Solution { + public int minSpeedOnTime(int[] dist, double hour) { + int start = 1; + int end = 1000_000_0; + int minSpeed = -1; + while (start <= end) { + int mid = (start + end) / 2; + if (isPossible(dist, mid, hour)) { + minSpeed = mid; + end = mid - 1; + } else { + start = mid + 1; + } + } + return minSpeed; + } + + private boolean isPossible(int[] dist, int speed, double hour) { + double totalTime = 0.0; + for (int i = 0; i < dist.length; i++) { + double time = (double) dist[i] / (double) speed; + totalTime += (i == dist.length - 1 ? time : Math.ceil(time)); + } + return totalTime <= hour; + } +} diff --git a/Medium/Minimum Swaps to Group All 1's Together.java b/Medium/Minimum Swaps to Group All 1's Together.java new file mode 100644 index 00000000..ea3d82c8 --- /dev/null +++ b/Medium/Minimum Swaps to Group All 1's Together.java @@ -0,0 +1,20 @@ +class Solution { + public int minSwaps(int[] data) { + int totalOnes = 0; + for (int num : data) { + totalOnes += num; + } + int leftIdx = 0; + int rightIdx = 0; + int currOnes = 0; + int maxOnes = 0; + while (rightIdx < data.length) { + currOnes += data[rightIdx++]; + if (rightIdx - leftIdx > totalOnes) { + currOnes -= data[leftIdx++]; + } + maxOnes = Math.max(maxOnes, currOnes); + } + return totalOnes - maxOnes; + } +} diff --git a/Medium/Minimum Time Difference.java b/Medium/Minimum Time Difference.java index a330bbea..b8ba42a1 100644 --- a/Medium/Minimum Time Difference.java +++ b/Medium/Minimum Time Difference.java @@ -1,23 +1,21 @@ class Solution { - public int findMinDifference(List timePoints) { - int[] mins = new int[timePoints.size()]; - int i = 0; - for (String s : timePoints) { - int hr = Integer.parseInt(s.split(":")[0]); - int ms = Integer.parseInt(s.split(":")[1]); - - mins[i] = hr*60 + ms; - i++; - } - - Arrays.sort(mins); - - int minTime = Integer.MAX_VALUE; - - for(int j=1;j timePoints) { + List minutes = new ArrayList<>(); + for (String timePoint : timePoints) { + minutes.add( + Integer.parseInt(timePoint.split(":")[0]) * 60 + + Integer.parseInt(timePoint.split(":")[1])); } + Collections.sort(minutes); + int prev = Integer.MIN_VALUE; + int minDiff = Integer.MAX_VALUE; + for (int minute : minutes) { + if (prev != Integer.MIN_VALUE) { + minDiff = Math.min(minDiff, minute - prev); + } + prev = minute; + } + minDiff = Math.min(minDiff, (24 * 60 - minutes.get(minutes.size() - 1) + minutes.get(0))); + return minDiff; + } } diff --git a/Medium/Minimum Time to Collect All Apples in a Tree.java b/Medium/Minimum Time to Collect All Apples in a Tree.java new file mode 100644 index 00000000..0e54b3ec --- /dev/null +++ b/Medium/Minimum Time to Collect All Apples in a Tree.java @@ -0,0 +1,27 @@ +class Solution { + public int minTime(int n, int[][] edges, List hasApple) { + Map> map = new HashMap<>(); + for (int[] edge : edges) { + map.computeIfAbsent(edge[0], k -> new ArrayList<>()).add(edge[1]); + map.computeIfAbsent(edge[1], k -> new ArrayList<>()).add(edge[0]); + } + return recurse(0, -1, map, hasApple); + } + + private int recurse(int node, int parent, Map> graph, List hasApple) { + if (!graph.containsKey(node)) { + return 0; + } + int time = 0; + for (Integer conn: graph.get(node)) { + if (conn == parent) { + continue; + } + int connTime = recurse(conn, node, graph, hasApple); + if (connTime > 0 || hasApple.get(conn)) { + time += connTime + 2; + } + } + return time; + } +} diff --git a/Medium/Minimum Time to Complete Trips.java b/Medium/Minimum Time to Complete Trips.java new file mode 100644 index 00000000..f6fa3539 --- /dev/null +++ b/Medium/Minimum Time to Complete Trips.java @@ -0,0 +1,27 @@ +class Solution { + public long minimumTime(int[] time, int totalTrips) { + int maxTime = 1; + for (int t : time) { + maxTime = Math.max(maxTime, t); + } + long left = 1; + long right = (long) maxTime * totalTrips; + while (left < right) { + long mid = (left + right) / 2; + if (isPossible(time, mid, totalTrips)) { + right = mid; + } else { + left = mid + 1; + } + } + return left; + } + + private boolean isPossible(int[] time, long totalTime, int totalTrips) { + long actualTrips = 0; + for (int t : time) { + actualTrips += totalTime / t; + } + return actualTrips >= totalTrips; + } +} diff --git a/Medium/Minimum Time to Make Rope Colorful.java b/Medium/Minimum Time to Make Rope Colorful.java new file mode 100644 index 00000000..3fdc7e26 --- /dev/null +++ b/Medium/Minimum Time to Make Rope Colorful.java @@ -0,0 +1,19 @@ +class Solution { + public int minCost(String colors, int[] neededTime) { + Stack stack = new Stack<>(); + int cost = 0; + for (int i = 0; i < colors.length(); i++) { + if (stack.isEmpty() || colors.charAt(i) != colors.charAt(stack.peek())) { + stack.push(i); + continue; + } + if (neededTime[i] > neededTime[stack.peek()]) { + cost += neededTime[stack.pop()]; + stack.push(i); + } else { + cost += neededTime[i]; + } + } + return cost; + } +} diff --git a/Medium/Mirror Reflection.java b/Medium/Mirror Reflection.java new file mode 100644 index 00000000..c5577abc --- /dev/null +++ b/Medium/Mirror Reflection.java @@ -0,0 +1,17 @@ +class Solution { + public int mirrorReflection(int p, int q) { + int extention = q; + int reflection = p; + while (extention % 2 == 0 && reflection % 2 == 0) { + extention /= 2; + reflection /= 2; + } + if (extention % 2 == 0 && reflection % 2 != 0) { + return 0; + } else if (extention % 2 != 0 && reflection % 2 == 0) { + return 2; + } else { + return 1; + } + } +} diff --git a/Medium/Missing Ranges.java b/Medium/Missing Ranges.java deleted file mode 100644 index 66d05e39..00000000 --- a/Medium/Missing Ranges.java +++ /dev/null @@ -1,25 +0,0 @@ -class Solution { - public List findMissingRanges(int[] nums, int lower, int upper) { - List ranges = new ArrayList<>(); - long currLower = (long) lower; - for (int i = 0; i < nums.length; i++) { - if (nums[i] < currLower) { - continue; - } - if (nums[i] == currLower) { - currLower++; - continue; - } - ranges.add(getRange(currLower, ((long) nums[i] - 1))); - currLower = ((long) nums[i]) + 1; - } - if (currLower <= upper) { - ranges.add(getRange(currLower, (long) upper)); - } - return ranges; - } - - private String getRange(long down, long up) { - return down == up ? String.valueOf(up) : down + "->" + up; - } -} diff --git a/Medium/Most Beautiful Item for Each Query.java b/Medium/Most Beautiful Item for Each Query.java new file mode 100644 index 00000000..5d2f75db --- /dev/null +++ b/Medium/Most Beautiful Item for Each Query.java @@ -0,0 +1,17 @@ +class Solution { + public int[] maximumBeauty(int[][] items, int[] queries) { + Arrays.sort(items, (a, b) -> (a[0] - b[0])); + TreeMap map = new TreeMap<>(); + map.put(0, 0); + int currMax = 0; + for (int[] item : items) { + currMax = Math.max(currMax, item[1]); + map.put(item[0], currMax); + } + int[] result = new int[queries.length]; + for (int i = 0; i < queries.length; i++) { + result[i] = map.floorEntry(queries[i]).getValue(); + } + return result; + } +} diff --git a/Medium/Most Frequent Subtree Sum.java b/Medium/Most Frequent Subtree Sum.java index a547b5ad..0d892dc1 100644 --- a/Medium/Most Frequent Subtree Sum.java +++ b/Medium/Most Frequent Subtree Sum.java @@ -4,53 +4,45 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - Map map = new HashMap<>(); - int max = 0; - public int[] findFrequentTreeSum(TreeNode root) { - populateSum(root); - - int count = 0; - - for (Map.Entry entry:map.entrySet()) { - if (entry.getValue() == max) { - count++; - } - } - - int[] ans = new int[count]; - int i = 0; - - for (Map.Entry entry:map.entrySet()) { - if (entry.getValue() == max) { - ans[i] = entry.getKey(); - i++; - } - } - - return ans; + public int[] findFrequentTreeSum(TreeNode root) { + Map subtreeSumFrequency = new HashMap<>(); + Map nodeToSum = new HashMap<>(); + dfsHelper(root, nodeToSum, subtreeSumFrequency); + int maxFrequency = subtreeSumFrequency.values().stream() + .max(Comparator.comparingInt(Integer::intValue)).orElseGet(() -> 0); + return subtreeSumFrequency + .keySet() + .stream() + .filter(e -> subtreeSumFrequency.get(e) == maxFrequency) + .collect(Collectors.toList()) + .stream() + .mapToInt(Integer::intValue) + .toArray(); + } + + private int dfsHelper(TreeNode node, Map nodeToSum, + Map subtreeSumFrequency) { + if (node == null) { + return 0; } - - public void populateSum(TreeNode root) { - - if (root == null) return; - int sum = getSum(root); - map.put(sum, map.getOrDefault(sum, 0) + 1); - - max = Math.max(max, map.get(sum)); - - populateSum(root.left); - populateSum(root.right); - - } - - public int getSum(TreeNode root) { - if (root == null) return 0; - - int sum = root.val; - return sum + getSum(root.left) + getSum(root.right); + if (nodeToSum.containsKey(node)) { + return nodeToSum.get(node); } + int leftSubtreeSum = dfsHelper(node.left, nodeToSum, subtreeSumFrequency); + int rightSubtreeSum = dfsHelper(node.right, nodeToSum, subtreeSumFrequency); + nodeToSum.put(node, node.val + leftSubtreeSum + rightSubtreeSum); + subtreeSumFrequency + .put(nodeToSum.get(node), subtreeSumFrequency.getOrDefault(nodeToSum.get(node), 0) + 1); + return nodeToSum.get(node); + } } diff --git a/Medium/Most Popular Video Creator.java b/Medium/Most Popular Video Creator.java new file mode 100644 index 00000000..d9e93554 --- /dev/null +++ b/Medium/Most Popular Video Creator.java @@ -0,0 +1,27 @@ +class Solution { + public List> mostPopularCreator(String[] creators, String[] ids, int[] views) { + Map creatorToViewCount = new HashMap<>(); + Map> creatorToIdWithMaxViews = new HashMap<>(); + long totalMaxViews = 0; + for (int i = 0; i < creators.length; i++) { + creatorToViewCount.put(creators[i], creatorToViewCount.getOrDefault(creators[i], 0L) + views[i]); + if (!creatorToIdWithMaxViews.containsKey(creators[i])) { + creatorToIdWithMaxViews.put(creators[i], new Pair<>(ids[i], (long) views[i])); + } else { + Pair currentIdToViewPair = creatorToIdWithMaxViews.get(creators[i]); + if (views[i] > currentIdToViewPair.getValue() || + (views[i] == currentIdToViewPair.getValue() && ids[i].compareTo(currentIdToViewPair.getKey()) < 0)) { + creatorToIdWithMaxViews.put(creators[i], new Pair<>(ids[i], (long) views[i])); + } + } + totalMaxViews = Math.max(totalMaxViews, creatorToViewCount.get(creators[i])); + } + List> result = new ArrayList<>(); + for (String key : creatorToViewCount.keySet()) { + if (creatorToViewCount.get(key) == totalMaxViews) { + result.add(Arrays.asList(key, creatorToIdWithMaxViews.get(key).getKey())); + } + } + return result; + } +} diff --git a/Medium/Most Profit Assigning Work.java b/Medium/Most Profit Assigning Work.java new file mode 100644 index 00000000..792530db --- /dev/null +++ b/Medium/Most Profit Assigning Work.java @@ -0,0 +1,31 @@ +class Solution { + public int maxProfitAssignment(int[] difficulty, int[] profit, int[] worker) { + List tasks = new ArrayList<>(); + for (int i = 0; i < difficulty.length; i++) { + tasks.add(new Task(profit[i], difficulty[i])); + } + tasks.sort(Comparator.comparingInt(o -> o.difficulty)); + Arrays.sort(worker); + int idx = 0; + int maxProfit = 0; + int workerProfit = 0; + for (int ability : worker) { + while (idx < profit.length && ability >= tasks.get(idx).difficulty) { + workerProfit = Math.max(workerProfit, tasks.get(idx++).profit); + } + maxProfit += workerProfit; + } + return maxProfit; + } + + + class Task { + int profit; + int difficulty; + + public Task(int profit, int difficulty) { + this.profit = profit; + this.difficulty = difficulty; + } + } +} diff --git a/Medium/Multiply Strings.java b/Medium/Multiply Strings.java index 9469b6cd..7222ae47 100644 --- a/Medium/Multiply Strings.java +++ b/Medium/Multiply Strings.java @@ -2,34 +2,29 @@ class Solution { public String multiply(String num1, String num2) { int m = num1.length(); int n = num2.length(); - int[] ans = new int[m + n]; - int idx = ans.length - 1; - for (int i = num1.length() - 1; i >= 0; i--) { - int currIdx = idx; + int[] result = new int[m + n]; + int endIdx = m + n - 1; + for (int i = m - 1; i >= 0; i--) { + int resultIdx = endIdx; int carry = 0; - for (int j = num2.length() - 1; j >= 0; j--) { - int temp = ( - ans[currIdx] + Character.getNumericValue(num1.charAt(i)) * Character.getNumericValue(num2.charAt(j)) + carry - ); - carry = temp > 9 ? temp / 10 : 0; - temp = temp > 9 ? temp % 10 : temp; - ans[currIdx--] = temp; + for (int j = n - 1; j >= 0; j--) { + int currValue = result[resultIdx] + carry + Character.getNumericValue(num1.charAt(i)) * Character.getNumericValue(num2.charAt(j)); + carry = currValue / 10; + result[resultIdx--] = currValue % 10; } while (carry > 0) { - int temp = ans[currIdx] + carry; - carry = temp > 9 ? temp / 10 : 0; - temp = temp > 9 ? temp % 10 : temp; - ans[currIdx--] = temp; + result[resultIdx--] = carry % 10; + carry /= 10; } - idx--; + endIdx--; } - int zeroIdx = 0; - while (zeroIdx < ans.length && ans[zeroIdx] == 0) { - zeroIdx++; + int idx = 0; + while (idx < result.length && result[idx] == 0) { + idx++; } StringBuilder sb = new StringBuilder(); - while (zeroIdx < ans.length) { - sb.append(ans[zeroIdx++]); + for (int i = idx; i < result.length; i++) { + sb.append(result[i]); } return sb.length() == 0 ? "0" : sb.toString(); } diff --git a/Medium/My Calendar I.java b/Medium/My Calendar I.java index c225f6b2..17064e87 100644 --- a/Medium/My Calendar I.java +++ b/Medium/My Calendar I.java @@ -1,21 +1,21 @@ class MyCalendar { - TreeMap map; - - public MyCalendar() { - map = new TreeMap<>(); - } - - public boolean book(int start, int end) { - Map.Entry entry = map.lowerEntry(end); - if (entry != null && entry.getValue() > start) { - return false; - } - - map.put(start, end); - return true; + + TreeMap events; + + public MyCalendar() { + events = new TreeMap<>(); + } + + public boolean book(int start, int end) { + Integer lower = events.floorKey(start); + Integer upper = events.ceilingKey(start); + if ((lower == null || events.get(lower) <= start) && (upper == null || end <= upper)) { + events.put(start, end); + return true; } + return false; + } } - /** * Your MyCalendar object will be instantiated and called as such: * MyCalendar obj = new MyCalendar(); diff --git a/Medium/My Calendar II.java b/Medium/My Calendar II.java index 4eb4e177..5553a51c 100644 --- a/Medium/My Calendar II.java +++ b/Medium/My Calendar II.java @@ -1,18 +1,20 @@ class MyCalendarTwo { - TreeMap map; + + private TreeMap delta; + public MyCalendarTwo() { - map = new TreeMap<>(); + this.delta = new TreeMap<>(); } public boolean book(int start, int end) { - map.put(start, map.getOrDefault(start, 0) + 1); - map.put(end, map.getOrDefault(end, 0) - 1); - int eventCount = 0; - for (int val : map.values()) { - eventCount += val; - if (eventCount >= 3) { - map.put(start, map.get(start) - 1); - map.put(end, map.get(end) + 1); + delta.put(start, delta.getOrDefault(start, 0) + 1); + delta.put(end, delta.getOrDefault(end, 0) - 1); + int active = 0; + for (int d : delta.values()) { + active += d; + if (active >= 3) { + delta.put(start, delta.get(start) - 1); + delta.put(end, delta.get(end) + 1); return false; } } diff --git a/Medium/N-ary Tree Level Order Traversal.java b/Medium/N-ary Tree Level Order Traversal.java new file mode 100644 index 00000000..7f3df2b3 --- /dev/null +++ b/Medium/N-ary Tree Level Order Traversal.java @@ -0,0 +1,40 @@ +/* +// Definition for a Node. +class Node { + public int val; + public List children; + + public Node() {} + + public Node(int _val) { + val = _val; + } + + public Node(int _val, List _children) { + val = _val; + children = _children; + } +}; +*/ + +class Solution { + public List> levelOrder(Node root) { + if (root == null) { + return new ArrayList<>(); + } + List> levels = new ArrayList<>(); + Queue queue = new LinkedList<>(); + queue.add(root); + while (!queue.isEmpty()) { + int size = queue.size(); + List currLevel = new ArrayList<>(); + while (size-- > 0) { + Node removed = queue.remove(); + currLevel.add(removed.val); + queue.addAll(removed.children); + } + levels.add(currLevel); + } + return levels; + } +} diff --git a/Medium/Nearest Exit from Entrance in Maze.java b/Medium/Nearest Exit from Entrance in Maze.java new file mode 100644 index 00000000..097d5aaa --- /dev/null +++ b/Medium/Nearest Exit from Entrance in Maze.java @@ -0,0 +1,45 @@ +class Solution { + private static final int[][] DIRS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; + + public int nearestExit(char[][] maze, int[] entrance) { + int rows = maze.length; + int cols = maze[0].length; + Queue queue = new LinkedList<>(); + boolean[][] visited = new boolean[rows][cols]; + int entranceRow = entrance[0]; + int entranceCol = entrance[1]; + queue.add(new int[]{entranceRow, entranceCol}); + visited[entranceRow][entranceCol] = true; + int steps = 0; + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + int[] removed = queue.remove(); + int row = removed[0]; + int col = removed[1]; + if (!(row == entranceRow && col == entranceCol) && isExit(row, col, rows, cols)) { + return steps; + } + for (int[] dir : DIRS) { + int newRow = row + dir[0]; + int newCol = col + dir[1]; + if (newRow >= 0 && + newCol >= 0 && + newRow < rows && + newCol < cols && + !visited[newRow][newCol] && + maze[newRow][newCol] != '+') { + queue.add(new int[]{newRow, newCol}); + visited[newRow][newCol] = true; + } + } + } + steps++; + } + return -1; + } + + private boolean isExit(int row, int col, int rows, int cols) { + return (row + 1 == rows) || (row - 1 == -1) || (col + 1 == cols) || (col - 1 == -1); + } +} diff --git a/Medium/Neighboring Bitwise XOR.java b/Medium/Neighboring Bitwise XOR.java new file mode 100644 index 00000000..6e46025c --- /dev/null +++ b/Medium/Neighboring Bitwise XOR.java @@ -0,0 +1,16 @@ +class Solution { + public boolean doesValidArrayExist(int[] derived) { + int n = derived.length; + int[] original = new int[n + 1]; + for (int i = 0; i < derived.length; i++) { + original[i + 1] = derived[i] ^ original[i]; + } + boolean checkForZero = (original[0] == original[n]); + original[0] = 1; + for (int i = 0; i < n; i++) { + original[i + 1] = derived[i] ^ original[i]; + } + boolean checkForOne = (original[0] == original[n]); + return checkForZero || checkForOne; + } +} diff --git a/Medium/Nested List Weight Sum II.java b/Medium/Nested List Weight Sum II.java index c5fcc6e8..f804c67b 100644 --- a/Medium/Nested List Weight Sum II.java +++ b/Medium/Nested List Weight Sum II.java @@ -22,36 +22,33 @@ * public void add(NestedInteger ni); * * // @return the nested list that this NestedInteger holds, if it holds a nested list - * // Return null if this NestedInteger holds a single integer + * // Return empty list if this NestedInteger holds a single integer * public List getList(); * } */ +import java.util.Map.Entry; + + class Solution { public int depthSumInverse(List nestedList) { Queue queue = new LinkedList<>(); - int prevSum = 0; + queue.addAll(nestedList); + int totalSum = 0; int currSum = 0; - for (NestedInteger nestedInteger : nestedList) { - queue.add(nestedInteger); - } while (!queue.isEmpty()) { int size = queue.size(); int levelSum = 0; while (size-- > 0) { - NestedInteger removed = queue.remove(); - if (removed.isInteger()) { - levelSum += removed.getInteger(); - } - else { - List nList = removed.getList(); - for (NestedInteger nInteger : nList) { - queue.add(nInteger); - } + NestedInteger nestedInteger = queue.remove(); + if (nestedInteger.isInteger()) { + levelSum += nestedInteger.getInteger(); + } else { + queue.addAll(nestedInteger.getList()); } } - prevSum += levelSum; - currSum += prevSum; + currSum += levelSum; + totalSum += currSum; } - return currSum; + return totalSum; } } diff --git a/Medium/Network Delay Time.java b/Medium/Network Delay Time.java index d1dc03be..2ee2990a 100644 --- a/Medium/Network Delay Time.java +++ b/Medium/Network Delay Time.java @@ -1,49 +1,35 @@ class Solution { - public int networkDelayTime(int[][] times, int N, int K) { - Map> map = new HashMap<>(); + public int networkDelayTime(int[][] times, int n, int k) { + Map> map = new HashMap<>(); for (int[] time : times) { - map.computeIfAbsent(time[0], k -> new ArrayList<>()).add(new Connection(time[1], time[2])); + map.computeIfAbsent(time[0], j -> new ArrayList<>()).add(new TimeNode(time[1], time[2])); } - Map dist = new HashMap<>(); - for (int node = 1; node <= N; node++) { - dist.put(node, Integer.MAX_VALUE); - } - dist.put(K, 0); - boolean[] seen = new boolean[N + 1]; - while (true) { - int candNode = -1; - int candDist = Integer.MAX_VALUE; - for (int i = 1; i <= N; ++i) { - if (!seen[i] && dist.get(i) < candDist) { - candDist = dist.get(i); - candNode = i; + PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt(o -> o.time)); + pq.add(new TimeNode(k, 0)); + int maxTime = 0; + Set visited = new HashSet<>(); + visited.add(k); + while (!pq.isEmpty() && visited.size() < n) { + TimeNode removed = pq.remove(); + visited.add(removed.node); + maxTime = Math.max(maxTime, removed.time); + for (TimeNode conn : map.getOrDefault(removed.node, new ArrayList<>())) { + if (visited.contains(conn.node)) { + continue; } - } - if (candNode < 0) { - break; - } - seen[candNode] = true; - for (Connection con: map.getOrDefault(candNode, new ArrayList<>())) { - dist.put(con.val, Math.min(dist.get(con.val), dist.get(candNode) + con.time)); + pq.add(new TimeNode(conn.node, removed.time + conn.time)); } } - int ans = 0; - for (int cand: dist.values()) { - if (cand == Integer.MAX_VALUE) { - return -1; - } - ans = Math.max(ans, cand); - } - return ans; + return visited.size() == n ? maxTime : -1; } -} - -class Connection { - int val; - int time; - public Connection(int val, int time) { - this.val = val; - this.time = time; + class TimeNode { + int node; + int time; + + public TimeNode(int node, int time) { + this.node = node; + this.time = time; + } } } diff --git a/Medium/New 21 Game.java b/Medium/New 21 Game.java new file mode 100644 index 00000000..26c88d90 --- /dev/null +++ b/Medium/New 21 Game.java @@ -0,0 +1,21 @@ +class Solution { + public double new21Game(int n, int k, int maxPts) { + double[] dp = new double[n + 1]; + dp[0] = 1; + double s = k > 0 ? 1 : 0; + for (int i = 1; i <= n; i++) { + dp[i] = s / maxPts; + if (i < k) { + s += dp[i]; + } + if (i - maxPts >= 0 && i - maxPts < k) { + s -= dp[i - maxPts]; + } + } + double result = 0; + for (int i = k; i <= n; i++) { + result += dp[i]; + } + return result; + } +} diff --git a/Medium/Next Closest Time.java b/Medium/Next Closest Time.java index 0d1ef172..46e267f6 100644 --- a/Medium/Next Closest Time.java +++ b/Medium/Next Closest Time.java @@ -1,42 +1,23 @@ class Solution { - public String nextClosestTime(String time) { - char[] timeDigits = time.toCharArray(); - char[] sorted = time.toCharArray(); - Arrays.sort(sorted); - - timeDigits[4] = findNext(timeDigits[4], (char)('9' + 1), sorted); - if (timeDigits[4] > time.charAt(4)) { - return String.valueOf(timeDigits); - } - - timeDigits[3] = findNext(timeDigits[3], '5', sorted); - if (timeDigits[3] > time.charAt(3)) { - return String.valueOf(timeDigits); - } - - timeDigits[1] = timeDigits[0] == '2' ? - findNext(timeDigits[1], '3', sorted) : - findNext(timeDigits[1], (char)('9' + 1), sorted); - if (timeDigits[1] > time.charAt(1)) { - return String.valueOf(timeDigits); - } - - timeDigits[0] = findNext(timeDigits[0], '2', sorted); - - return String.valueOf(timeDigits); + public String nextClosestTime(String time) { + int minutes = Integer.parseInt(time.substring(0, 2)) * 60 + Integer.parseInt(time.substring(3)); + Set digits = new HashSet<>(); + for (char c : time.toCharArray()) { + digits.add(c - '0'); } - - private char findNext(char current, char limit, char[] sorted) { - if (current == limit) { - return sorted[0]; - } - - int pos = Arrays.binarySearch(sorted, current) + 1; - - while (pos < 4 && (sorted[pos] > limit || sorted[pos] == current)) { - pos++; + while (true) { + minutes = (minutes + 1) % (24 * 60); + int[] nextTime = {minutes / 60 / 10, minutes / 60 % 10, minutes % 60 / 10, minutes % 60 % 10}; + boolean found = true; + for (int unit : nextTime) { + if (!digits.contains(unit)) { + found = false; + break; } - - return pos == 4 ? sorted[0] : sorted[pos]; + } + if (found) { + return String.format("%02d:%02d", minutes / 60, minutes % 60); + } } + } } diff --git a/Medium/Next Greater Element II.java b/Medium/Next Greater Element II.java index 367351ae..c392b087 100644 --- a/Medium/Next Greater Element II.java +++ b/Medium/Next Greater Element II.java @@ -1,23 +1,23 @@ class Solution { public int[] nextGreaterElements(int[] nums) { - int[] ans = new int[nums.length]; + int[] result = new int[nums.length]; Stack stack = new Stack<>(); for (int i = nums.length - 1; i >= 0; i--) { while (!stack.isEmpty() && nums[stack.peek()] <= nums[i]) { stack.pop(); } - ans[i] = stack.isEmpty() ? -1 : nums[stack.peek()]; + result[i] = stack.isEmpty() ? -1 : nums[stack.peek()]; stack.push(i); } for (int i = nums.length - 1; i >= 0; i--) { - if (ans[i] == -1) { + if (result[i] == -1) { while (!stack.isEmpty() && nums[stack.peek()] <= nums[i]) { stack.pop(); } - ans[i] = stack.isEmpty() ? -1 : nums[stack.peek()]; + result[i] = stack.isEmpty() ? -1 : nums[stack.peek()]; } stack.push(i); } - return ans; + return result; } } diff --git a/Medium/Next Greater Element III.java b/Medium/Next Greater Element III.java index 0d0592ef..92d84436 100644 --- a/Medium/Next Greater Element III.java +++ b/Medium/Next Greater Element III.java @@ -1,53 +1,33 @@ class Solution { - public int nextGreaterElement(int n) { - int[] arr = getArr(n); - int i; - for (i=arr.length-1; i>0; i--) { - if (arr[i-1] < arr[i]) { - break; - } + public int nextGreaterElement(int n) { + char[] digits = String.valueOf(n).toCharArray(); + int idx = digits.length - 2; + while (idx >= 0) { + if (Character.getNumericValue(digits[idx]) < Character.getNumericValue(digits[idx + 1])) { + int secondIdx = digits.length - 1; + while (secondIdx >= idx && digits[secondIdx] <= digits[idx]) { + secondIdx--; + } + swap(digits, idx, secondIdx); + int start = idx + 1; + int end = digits.length - 1; + while (start < end) { + swap(digits, start++, end--); } - - if (i == 0) { - return -1; + try { + return Integer.parseInt(new String(digits)); + } catch (Exception e) { + return -1; } - - int num = arr[i-1]; - int small = i; - for (int j=i+1; j num && arr[j] <= arr[small]) { - small = j; - } - } - - int temp = arr[i-1]; - arr[i-1] = arr[small]; - arr[small] = temp; - - Arrays.sort(arr, i, arr.length); - long ans = getNumber(arr); - - return ans <= Integer.MAX_VALUE ? (int) ans : -1; - } - - private long getNumber(int[] arr) { - long num = 0; - for (int i=0; i= 0) { - arr[i] = n % 10; - n /= 10; - i--; - } - - return arr; + } + idx--; } + return -1; + } + + private void swap(char[] digits, int idxOne, int idxTwo) { + char temp = digits[idxOne]; + digits[idxOne] = digits[idxTwo]; + digits[idxTwo] = temp; + } } diff --git a/Medium/Next Greater Numerically Balanced Number.java b/Medium/Next Greater Numerically Balanced Number.java new file mode 100644 index 00000000..c5b399c5 --- /dev/null +++ b/Medium/Next Greater Numerically Balanced Number.java @@ -0,0 +1,6 @@ +class Solution { + public final int[] CANDIDATES = new int[] {1, 22, 122, 212, 221, 333, 1333, 3133, 3313, 3331, 4444, 14444, 22333, 23233, 23323, 23332, 32233, 32323, 32332, 33223, 33232, 33322, 41444, 44144, 44414, 44441, 55555, 122333, 123233, 123323, 123332, 132233, 132323, 132332, 133223, 133232, 133322, 155555, 212333, 213233, 213323, 213332, 221333, 223133, 223313, 223331, 224444, 231233, 231323, 231332, 232133, 232313, 232331, 233123, 233132, 233213, 233231, 233312, 233321, 242444, 244244, 244424, 244442, 312233, 312323, 312332, 313223, 313232, 313322, 321233, 321323, 321332, 322133, 322313, 322331, 323123, 323132, 323213, 323231, 323312, 323321, 331223, 331232, 331322, 332123, 332132, 332213, 332231, 332312, 332321, 333122, 333212, 333221, 422444, 424244, 424424, 424442, 442244, 442424, 442442, 444224, 444242, 444422, 515555, 551555, 555155, 555515, 555551, 666666}; + public int nextBeautifulNumber(int n) { + return Arrays.stream(CANDIDATES).filter(candidate -> candidate > n).findFirst().orElse(1224444); + } +} diff --git a/Medium/Next Permutation.java b/Medium/Next Permutation.java index a29876cb..b08a0001 100644 --- a/Medium/Next Permutation.java +++ b/Medium/Next Permutation.java @@ -1,32 +1,31 @@ class Solution { - public void nextPermutation(int[] nums) { - boolean flag = true; - int right = nums.length - 1; - int start = right; - while (start >= 1) { - if (nums[start] > nums[start - 1]) { - int idx = right; - while (nums[idx] <= nums[start - 1]) { - idx--; + public void nextPermutation(int[] nums) { + int n = nums.length; + int pivot = n - 1; + // Find the first value where decreasing order doesn't holds + while (pivot > 0 && nums[pivot] <= nums[pivot - 1]) { + pivot--; + } + if (pivot != 0) { + int i = n - 1; + // Find the first value from right to left which is greater than element at + // pivot - 1 + while (nums[i] <= nums[pivot - 1]) { + i--; + } + swap(nums, pivot - 1, i); + } + // Reverse the complete array + int left = pivot; + int right = n - 1; + while (left < right) { + swap(nums, left++, right--); } - int temp = nums[start - 1]; - nums[start - 1] = nums[idx]; - nums[idx] = temp; - flag = false; - break; - } - start--; - } - if (flag) { - Arrays.sort(nums); - return; } - while (start < right) { - int temp = nums[start]; - nums[start] = nums[right]; - nums[right] = temp; - start++; - right--; + + private void swap(int[] nums, int idxOne, int idxTwo) { + int temp = nums[idxOne]; + nums[idxOne] = nums[idxTwo]; + nums[idxTwo] = temp; } - } } diff --git a/Medium/Node With Highest Edge Score.java b/Medium/Node With Highest Edge Score.java new file mode 100644 index 00000000..9154bb2f --- /dev/null +++ b/Medium/Node With Highest Edge Score.java @@ -0,0 +1,19 @@ +class Solution { + public int edgeScore(int[] edges) { + Map map = new HashMap<>(); + int highestScore = 0; + int highestScoreCandidate = Integer.MAX_VALUE; + for (int i = 0; i < edges.length; i++) { + map.put(edges[i], map.getOrDefault(edges[i], 0) + i); + if (highestScore <= map.get(edges[i])) { + if (highestScore < map.get(edges[i])) { + highestScore = map.get(edges[i]); + highestScoreCandidate = edges[i]; + } else if (highestScore == map.get(edges[i]) && highestScoreCandidate > edges[i]) { + highestScoreCandidate = edges[i]; + } + } + } + return highestScoreCandidate; + } +} diff --git a/Medium/Non Overlapping Intervals.java b/Medium/Non Overlapping Intervals.java deleted file mode 100644 index cbdae574..00000000 --- a/Medium/Non Overlapping Intervals.java +++ /dev/null @@ -1,17 +0,0 @@ -class Solution { - public int eraseOverlapIntervals(int[][] intervals) { - if (intervals.length == 0) { - return 0; - } - Arrays.sort(intervals, Comparator.comparingInt(o -> o[1])); - int notRemoved = 1; - int end = intervals[0][1]; - for (int i = 1; i < intervals.length; i++) { - if (intervals[i][0] >= end) { - notRemoved++; - end = intervals[i][1]; - } - } - return intervals.length - notRemoved; - } -} diff --git a/Medium/Non-decreasing Array.java b/Medium/Non-decreasing Array.java new file mode 100644 index 00000000..489db551 --- /dev/null +++ b/Medium/Non-decreasing Array.java @@ -0,0 +1,19 @@ +class Solution { + public boolean checkPossibility(int[] nums) { + boolean mismatch = false; + for (int i = 1; i < nums.length; i++) { + if (nums[i - 1] > nums[i]) { + if (mismatch) { + return false; + } + if (i < 2 || nums[i - 2] <= nums[i]) { + nums[i - 1] = nums[i]; + } else { + nums[i] = nums[i - 1]; + } + mismatch = true; + } + } + return true; + } +} diff --git a/Medium/Non-overlapping Intervals.java b/Medium/Non-overlapping Intervals.java new file mode 100644 index 00000000..c403b5ed --- /dev/null +++ b/Medium/Non-overlapping Intervals.java @@ -0,0 +1,17 @@ +class Solution { + public int eraseOverlapIntervals(int[][] intervals) { + Arrays.sort(intervals, Comparator.comparingInt((int[] o) -> o[1])); + int result = 0; + int minEndTime = Integer.MIN_VALUE; + for (int i = 0; i < intervals.length; i++) { + int start = intervals[i][0]; + int end = intervals[i][1]; + if (start >= minEndTime) { + minEndTime = end; + } else { + result++; + } + } + return result; + } +} diff --git a/Medium/Number of Closed Islands.java b/Medium/Number of Closed Islands.java new file mode 100644 index 00000000..bc8a9a9e --- /dev/null +++ b/Medium/Number of Closed Islands.java @@ -0,0 +1,38 @@ +class Solution { + + private static final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + + public int closedIsland(int[][] grid) { + int count = 0; + boolean[][] visited = new boolean[grid.length][grid[0].length]; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 0 && !visited[i][j] && isClosed(grid, i, j, visited)) { + count++; + } + } + } + return count; + } + + private boolean isClosed(int[][] grid, int i, int j, boolean[][] visited) { + Queue queue = new LinkedList<>(); + queue.add(new int[]{i, j}); + visited[i][j] = true; + boolean closed = true; + while (!queue.isEmpty()) { + int[] removed = queue.remove(); + for (int[] dir : DIRS) { + int newX = removed[0] + dir[0]; + int newY = removed[1] + dir[1]; + if (newX < 0 || newY < 0 || newX >= grid.length || newY >= grid[0].length) { + closed = false; + } else if (grid[newX][newY] == 0 && !visited[newX][newY]) { + queue.add(new int[]{newX, newY}); + visited[newX][newY] = true; + } + } + } + return closed; + } +} diff --git a/Medium/Number of Connected Components in an Undirected Graph.java b/Medium/Number of Connected Components in an Undirected Graph.java index 2c81b9ee..59e0be29 100644 --- a/Medium/Number of Connected Components in an Undirected Graph.java +++ b/Medium/Number of Connected Components in an Undirected Graph.java @@ -1,41 +1,29 @@ class Solution { public int countComponents(int n, int[][] edges) { - Map> map = new HashMap<>(); - + Map> graph = new HashMap<>(); for (int[] edge : edges) { - map.computeIfAbsent(edge[0], k -> new ArrayList()).add(edge[1]); - map.computeIfAbsent(edge[1], k -> new ArrayList()).add(edge[0]); + graph.computeIfAbsent(edge[0], k -> new HashSet<>()).add(edge[1]); + graph.computeIfAbsent(edge[1], k -> new HashSet<>()).add(edge[0]); } - - Set set = new HashSet<>(); - int count = 0; - - for (Map.Entry> entry : map.entrySet()) { - if (set.contains(entry.getKey())) { - continue; - } - - Queue queue = new LinkedList<>(); - queue.add(entry.getKey()); - set.add(entry.getKey()); - - while (!queue.isEmpty()) { - int popped = queue.remove(); - List connections = map.getOrDefault(popped, new ArrayList()); - - for (int connection : connections) { - if (set.contains(connection)) { - continue; + int connectedComponentCount = 0; + Set visited = new HashSet<>(); + for (int i = 0; i < n; i++) { + if (!visited.contains(i)) { + Queue queue = new LinkedList<>(); + visited.add(i); + queue.add(i); + while (!queue.isEmpty()) { + int removed = queue.remove(); + for (Integer neighbor : graph.getOrDefault(removed, new HashSet<>())) { + if (!visited.contains(neighbor)) { + queue.add(neighbor); + visited.add(neighbor); + } } - - set.add(connection); - queue.add(connection); } + connectedComponentCount++; } - - count++; } - - return count + (n - set.size()); + return connectedComponentCount; } } diff --git a/Medium/Number of Dice Rolls With Target Sum.java b/Medium/Number of Dice Rolls With Target Sum.java index 6e600168..e192518a 100644 --- a/Medium/Number of Dice Rolls With Target Sum.java +++ b/Medium/Number of Dice Rolls With Target Sum.java @@ -1,27 +1,31 @@ class Solution { - Map map = new HashMap<>(); - final int MODULO = 1000000007; - public int numRollsToTarget(int d, int f, int target) { - if (d == 0 && target == 0) { - return 1; + + private static final int MOD = 1000_000_007; + + public int numRollsToTarget(int n, int k, int target) { + Map map = new HashMap<>(); + return helper(n, k, target, map); } - if (d == 0 || target == 0) { - return 0; + + private int helper(int n, int k, int target, Map map) { + if (n == 0 && target == 0) { + return 1; + } + if (n == 0 || target == 0) { + return 0; + } + int key = n * 1000 + target; + if (map.containsKey(key)) { + return map.get(key); + } + int result = 0; + for (int i = 1; i <= k; i++) { + if (target < i) { + break; + } + result = (result + helper(n - 1, k, target - i, map)) % MOD; + } + map.put(key, result); + return result; } - String key = d + "|" + target; - if (map.containsKey(key)) { - return map.get(key); - } - int res = 0; - for (int i = 1; i <= f; i++) { - if (target >= i) { - res = (res + numRollsToTarget(d - 1, f, target - i)) % MODULO; - } - else { - break; - } - } - map.put(key, res); - return map.get(key); - } } diff --git a/Medium/Number of Distinct Islands.java b/Medium/Number of Distinct Islands.java index d33af963..e9ea1286 100644 --- a/Medium/Number of Distinct Islands.java +++ b/Medium/Number of Distinct Islands.java @@ -1,38 +1,35 @@ class Solution { - Set set; - int[][] dirs = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}}; public int numDistinctIslands(int[][] grid) { - if (grid.length == 0 || grid[0].length == 0) { - return 0; - } - set = new HashSet<>(); - boolean[][] visited = new boolean[grid.length][grid[0].length]; - for (int i = 0; i < grid.length; i++) { - for (int j = 0; j < grid[i].length; j++) { - if (!visited[i][j]) { - StringBuilder sb = new StringBuilder(); - dfs(grid, i, j, visited, sb, 0); - if (sb.length() > 0) { - set.add(sb.toString()); - } + int rows = grid.length; + int cols = grid[0].length; + boolean[][] visited = new boolean[rows][cols]; + Set islands = new HashSet<>(); + for (int row = 0; row < rows; row++) { + for (int col = 0; col < cols; col++) { + StringBuilder currIsland = new StringBuilder(); + dfs(grid, row, col, visited, currIsland, '0'); + if (currIsland.length() == 0) { + continue; } + islands.add(currIsland.toString()); } } - return set.size(); + return islands.size(); } - private void dfs(int[][] grid, int x, int y, boolean[][] visited, StringBuilder sb, int currDir) { - if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] != 1 || visited[x][y]) { + private void dfs(int[][] grid, int row, int col, boolean[][] visited, StringBuilder currIsland, char direction) { + if (row < 0 || row >= grid.length || col < 0 || col >= grid[0].length) { return; } - sb.append(currDir); - visited[x][y] = true; - int curr = 1; - for (int[] dir : dirs) { - int newX = x + dir[0]; - int newY = y + dir[1]; - dfs(grid, newX, newY, visited, sb, curr++); + if (visited[row][col] || grid[row][col] == 0) { + return; } - sb.append(0); + visited[row][col] = true; + currIsland.append(direction); + dfs(grid, row + 1, col, visited, currIsland, 'D'); + dfs(grid, row - 1, col, visited, currIsland, 'U'); + dfs(grid, row, col + 1, visited, currIsland, 'R'); + dfs(grid, row, col - 1, visited, currIsland, 'L'); + currIsland.append('0'); } } diff --git a/Medium/Number of Distinct Substrings in a String.java b/Medium/Number of Distinct Substrings in a String.java new file mode 100644 index 00000000..17d2a053 --- /dev/null +++ b/Medium/Number of Distinct Substrings in a String.java @@ -0,0 +1,26 @@ +class Solution { + public int countDistinct(String s) { + TrieNode root = new TrieNode(); + int n = s.length(); + int count = 0; + for (int i = 0; i < n; i++) { + TrieNode curr = root; + for (int j = i; j < n; j++) { + if (!curr.children.containsKey(s.charAt(j))) { + count++; + curr.children.put(s.charAt(j), new TrieNode()); + } + curr = curr.children.get(s.charAt(j)); + } + } + return count; + } + + private static class TrieNode { + Map children; + + public TrieNode() { + this.children = new HashMap<>(); + } + } +} diff --git a/Medium/Number of Enclaves.java b/Medium/Number of Enclaves.java new file mode 100644 index 00000000..afacc77a --- /dev/null +++ b/Medium/Number of Enclaves.java @@ -0,0 +1,40 @@ +class Solution { + + private static final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + + public int numEnclaves(int[][] grid) { + int count = 0; + boolean[][] visited = new boolean[grid.length][grid[0].length]; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 1 && !visited[i][j]) { + count += getClosedEnclaveCount(grid, i, j, visited); + } + } + } + return count; + } + + private int getClosedEnclaveCount(int[][] grid, int i, int j, boolean[][] visited) { + boolean isClosed = true; + int enclaveCount = 0; + Queue queue = new LinkedList<>(); + queue.add(new int[]{i, j}); + visited[i][j] = true; + while (!queue.isEmpty()) { + int[] removed = queue.remove(); + enclaveCount++; + for (int[] dir : DIRS) { + int newX = removed[0] + dir[0]; + int newY = removed[1] + dir[1]; + if (newX < 0 || newY < 0 || newX >= grid.length || newY >= grid[0].length) { + isClosed = false; + } else if (grid[newX][newY] == 1 && !visited[newX][newY]) { + visited[newX][newY] = true; + queue.add(new int[]{newX, newY}); + } + } + } + return isClosed ? enclaveCount : 0; + } +} diff --git a/Medium/Number of Good Leaf Nodes Pairs.java b/Medium/Number of Good Leaf Nodes Pairs.java new file mode 100644 index 00000000..c54d967f --- /dev/null +++ b/Medium/Number of Good Leaf Nodes Pairs.java @@ -0,0 +1,59 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public int countPairs(TreeNode root, int distance) { + Map> graph = new HashMap<>(); + Set leaves = new HashSet<>(); + traverse(root, null, graph, leaves); + int result = 0; + for (TreeNode leaf : leaves) { + Queue queue = new LinkedList<>(); + Set visited = new HashSet<>(); + queue.add(leaf); + visited.add(leaf); + for (int i = 0; i <= distance; i++) { + int size = queue.size(); + while (size-- > 0) { + TreeNode curr = queue.remove(); + if (leaves.contains(curr) && curr != leaf) { + result++; + } + for (TreeNode neighbor : graph.getOrDefault(curr, new ArrayList<>())) { + if (visited.add(neighbor)) { + queue.add(neighbor); + } + } + } + } + } + return result / 2; + } + + private void traverse(TreeNode node, TreeNode parent, Map> graph, Set leaves) { + if (node == null) { + return; + } + if (node.left == null && node.right == null) { + leaves.add(node); + } + if (parent != null) { + graph.computeIfAbsent(parent, k -> new ArrayList<>()).add(node); + graph.computeIfAbsent(node, k -> new ArrayList<>()).add(parent); + } + traverse(node.left, node, graph, leaves); + traverse(node.right, node, graph, leaves); + } +} diff --git a/Medium/Number of Islands.java b/Medium/Number of Islands.java index 1d6c2a87..ecf3afb7 100644 --- a/Medium/Number of Islands.java +++ b/Medium/Number of Islands.java @@ -1,13 +1,12 @@ class Solution { + + private static final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + public int numIslands(char[][] grid) { - if (grid.length == 0 || grid[0].length == 0) { - return 0; - } int rows = grid.length; int cols = grid[0].length; - int[][] dirs = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; boolean[][] visited = new boolean[rows][cols]; - int count = 0; + int islandCount = 0; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (grid[i][j] == '1' && !visited[i][j]) { @@ -16,20 +15,19 @@ public int numIslands(char[][] grid) { visited[i][j] = true; while (!queue.isEmpty()) { int[] removed = queue.remove(); - for (int[] dir : dirs) { + for (int[] dir : DIRS) { int newX = removed[0] + dir[0]; int newY = removed[1] + dir[1]; - if (newX < 0 || newX >= rows || newY < 0 || newY >= cols || visited[newX][newY] || grid[newX][newY] == '0') { - continue; + if (newX >= 0 && newY >= 0 && newX < rows && newY < cols && !visited[newX][newY] && grid[newX][newY] == '1') { + visited[newX][newY] = true; + queue.add(new int[]{newX, newY}); } - visited[newX][newY] = true; - queue.add(new int[]{newX, newY}); } } - count++; + islandCount++; } } } - return count; + return islandCount; } } diff --git a/Medium/Number of Laser Beams in a Bank.java b/Medium/Number of Laser Beams in a Bank.java new file mode 100644 index 00000000..ce39e8bd --- /dev/null +++ b/Medium/Number of Laser Beams in a Bank.java @@ -0,0 +1,17 @@ +class Solution { + public int numberOfBeams(String[] bank) { + int beamCount = 0; + int prevLaserCount = 0; + for (String row : bank) { + int count = 0; + for (char c : row.toCharArray()) { + count += c == '1' ? 1 : 0; + } + if (count > 0) { + beamCount += prevLaserCount * count; + prevLaserCount = count; + } + } + return beamCount; + } +} diff --git a/Medium/Number of Matching Subsequences.java b/Medium/Number of Matching Subsequences.java new file mode 100644 index 00000000..355527ee --- /dev/null +++ b/Medium/Number of Matching Subsequences.java @@ -0,0 +1,24 @@ +class Solution { + public int numMatchingSubseq(String s, String[] words) { + Map> map = new HashMap<>(); + for (int i = 0; i < words.length; i++) { + map.computeIfAbsent(words[i].charAt(0), k -> new ArrayList<>()).add(new int[]{0, i}); + } + int result = 0; + for (char c : s.toCharArray()) { + List values = map.getOrDefault(c, new ArrayList<>()); + map.put(c, new ArrayList<>()); + for (int[] val : values) { + int stringIdx = val[0]; + int wordIdx = val[1]; + if (stringIdx + 1 == words[wordIdx].length()) { + result++; + } else { + char nextChar = words[wordIdx].charAt(stringIdx + 1); + map.computeIfAbsent(nextChar, k -> new ArrayList<>()).add(new int[]{stringIdx + 1, wordIdx}); + } + } + } + return result; + } +} diff --git a/Medium/Number of Nodes in the Sub-Tree With the Same Label.java b/Medium/Number of Nodes in the Sub-Tree With the Same Label.java index 473b9052..1798a058 100644 --- a/Medium/Number of Nodes in the Sub-Tree With the Same Label.java +++ b/Medium/Number of Nodes in the Sub-Tree With the Same Label.java @@ -1,30 +1,28 @@ class Solution { - public int[] countSubTrees(int n, int[][] edges, String labels) { - Map> map = new HashMap<>(); - for (int[] edge : edges) { - map.computeIfAbsent(edge[0], k -> new ArrayList<>()).add(edge[1]); - map.computeIfAbsent(edge[1], k -> new ArrayList<>()).add(edge[0]); - } - int[] count = new int[n]; - Set set = new HashSet<>(); - dfs(map, 0, labels, count, set); - return count; - } - - private int[] dfs(Map> map, int curr, String labels, int[] count, Set set) { - int[] cnt = new int[26]; - if (set.add(curr)) { - char c = labels.charAt(curr); - for (Integer child : map.getOrDefault(curr, new ArrayList<>())) { - int[] temp = dfs(map, child, labels, count, set); - for (int i = 0; i < 26; i++) { - cnt[i] += temp[i]; + public int[] countSubTrees(int n, int[][] edges, String labels) { + Map> tree = new HashMap<>(); + for (int[] edge : edges) { + tree.computeIfAbsent(edge[0], k -> new ArrayList<>()).add(edge[1]); + tree.computeIfAbsent(edge[1], k -> new ArrayList<>()).add(edge[0]); + } + int[] result = new int[n]; + Set visited = new HashSet<>(); + bfs(tree, 0, labels, result, visited); + return result; + } + + private int[] bfs(Map> tree, int currNode, String labels, int[] result, Set visited) { + int[] labelCount = new int[26]; + if (visited.add(currNode)) { + labelCount[labels.charAt(currNode) - 'a']++; + for (Integer child : tree.getOrDefault(currNode, new ArrayList<>())) { + int[] childLabelCount = bfs(tree, child, labels, result, visited); + for (int i = 0; i < 26; i++) { + labelCount[i] += childLabelCount[i]; + } + } + result[currNode] += labelCount[labels.charAt(currNode) - 'a']; } - } - cnt[c - 'a']++; - count[curr] = cnt[c - 'a']; + return labelCount; } - return cnt; - } } - diff --git a/Medium/Number of Operations to Make Network Connected.java b/Medium/Number of Operations to Make Network Connected.java new file mode 100644 index 00000000..c44c17d8 --- /dev/null +++ b/Medium/Number of Operations to Make Network Connected.java @@ -0,0 +1,36 @@ +class Solution { + public int makeConnected(int n, int[][] connections) { + if (connections.length < n - 1) { + return -1; + } + Map> graph = new HashMap<>(); + for (int[] conn : connections) { + graph.computeIfAbsent(conn[0], k -> new HashSet<>()).add(conn[1]); + graph.computeIfAbsent(conn[1], k -> new HashSet<>()).add(conn[0]); + } + int count = 0; + boolean[] visited = new boolean[n]; + for (int i = 0; i < n; i++) { + if (!visited[i]) { + bfs(graph, i, visited); + count++; + } + } + return count - 1; + } + + private void bfs(Map> graph, int start, boolean[] visited) { + Queue queue = new LinkedList<>(); + queue.add(start); + visited[start] = true; + while (!queue.isEmpty()) { + int removed = queue.remove(); + for (Integer node : graph.getOrDefault(removed, new HashSet<>())) { + if (!visited[node]) { + visited[node] = true; + queue.add(node); + } + } + } + } +} diff --git a/Medium/Number of Pairs of Interchangeable Rectangles.java b/Medium/Number of Pairs of Interchangeable Rectangles.java new file mode 100644 index 00000000..e8e6ef9f --- /dev/null +++ b/Medium/Number of Pairs of Interchangeable Rectangles.java @@ -0,0 +1,11 @@ +class Solution { + public long interchangeableRectangles(int[][] rectangles) { + return Arrays.stream(rectangles) + .collect(Collectors.groupingBy( + e -> ((double) e[0]) / e[1], HashMap::new, Collectors.counting())) + .values() + .stream() + .map(v -> (v * (v - 1)) / 2) + .reduce(0L, Long::sum); + } +} diff --git a/Medium/Number of Pairs of Strings With Concatenation Equal to Target.java b/Medium/Number of Pairs of Strings With Concatenation Equal to Target.java new file mode 100644 index 00000000..be6a6077 --- /dev/null +++ b/Medium/Number of Pairs of Strings With Concatenation Equal to Target.java @@ -0,0 +1,18 @@ +class Solution { + public int numOfPairs(String[] nums, String target) { + Map map = new HashMap<>(); + int count = 0; + for (String num : nums) { + if (target.startsWith(num)) { + String end = target.substring(num.length()); + count += map.getOrDefault(end, 0); + } + if (target.endsWith(num)) { + String start = target.substring(0, target.length() - num.length()); + count += map.getOrDefault(start, 0); + } + map.put(num, map.getOrDefault(num, 0) + 1); + } + return count; + } +} diff --git a/Medium/Number of Provinces.java b/Medium/Number of Provinces.java new file mode 100644 index 00000000..03338dd8 --- /dev/null +++ b/Medium/Number of Provinces.java @@ -0,0 +1,37 @@ +class Solution { + public int findCircleNum(int[][] isConnected) { + Map> graph = new HashMap<>(); + for (int i = 0; i < isConnected.length; i++) { + for (int j = 0; j < isConnected[i].length; j++) { + if (i != j && isConnected[i][j] == 1) { + graph.computeIfAbsent(i, k -> new HashSet<>()).add(j); + graph.computeIfAbsent(j, k -> new HashSet<>()).add(i); + } + } + } + Set visited = new HashSet<>(); + int provinces = 0; + for (int i = 0; i < isConnected.length; i++) { + if (!visited.contains(i)) { + traverse(graph, i, visited); + provinces++; + } + } + return provinces; + } + + private void traverse(Map> graph, int city, Set visited) { + Queue queue = new LinkedList<>(); + queue.add(city); + visited.add(city); + while (!queue.isEmpty()) { + int removed = queue.remove(); + for (Integer conn : graph.getOrDefault(removed, new HashSet<>())) { + if (!visited.contains(conn)) { + queue.add(conn); + visited.add(conn); + } + } + } + } +} diff --git a/Medium/Number of Same-End Substrings.java b/Medium/Number of Same-End Substrings.java new file mode 100644 index 00000000..4003737d --- /dev/null +++ b/Medium/Number of Same-End Substrings.java @@ -0,0 +1,28 @@ +class Solution { + public int[] sameEndSubstringCount(String s, int[][] queries) { + int n = s.length(); + int[][] prefixSum = new int[26][n]; + for (int i = 0; i < n; i++) { + prefixSum[s.charAt(i) - 'a'][i]++; + } + for (int i = 0; i < 26; i++) { + for (int j = 1; j < n; j++) { + prefixSum[i][j] += prefixSum[i][j - 1]; + } + } + int[] result = new int[queries.length]; + for (int i = 0; i < queries.length; i++) { + int left = queries[i][0]; + int right = queries[i][1]; + int count = 0; + for (int c = 0; c < 26; c++) { + int leftFreq = left == 0 ? 0 : prefixSum[c][left - 1]; + int rightFreq = prefixSum[c][right]; + int freqInRange = rightFreq - leftFreq; + count += (freqInRange * (freqInRange + 1)) / 2; + } + result[i] = count; + } + return result; + } +} diff --git a/Medium/Number of Smooth Descent Periods of a Stock.java b/Medium/Number of Smooth Descent Periods of a Stock.java new file mode 100644 index 00000000..34f34227 --- /dev/null +++ b/Medium/Number of Smooth Descent Periods of a Stock.java @@ -0,0 +1,16 @@ +class Solution { + public long getDescentPeriods(int[] prices) { + long smoothDescentPeriods = 0; + int idx = 0; + while (idx < prices.length) { + long currentDescentPeriod = 1; + idx++; + while (idx < prices.length && prices[idx - 1] - prices[idx] == 1) { + currentDescentPeriod++; + idx++; + } + smoothDescentPeriods += currentDescentPeriod * (currentDescentPeriod + 1) / 2; + } + return smoothDescentPeriods; + } +} diff --git a/Medium/Number of Steps to Reduce a Number in Binary Representation to One.java b/Medium/Number of Steps to Reduce a Number in Binary Representation to One.java new file mode 100644 index 00000000..00a8296a --- /dev/null +++ b/Medium/Number of Steps to Reduce a Number in Binary Representation to One.java @@ -0,0 +1,27 @@ +class Solution { + public int numSteps(String s) { + int operations = 0; + StringBuilder sb = new StringBuilder(s); + while (sb.length() > 1) { + int n = sb.length(); + if (sb.charAt(n - 1) == '0') { + // divide by 2 + sb.deleteCharAt(n - 1); + } else { + // add 1 + int idx = n - 1; + while (idx >= 0 && sb.charAt(idx) != '0') { + sb.setCharAt(idx, '0'); + idx--; + } + if (idx < 0) { + sb.insert(0, '1'); + } else { + sb.setCharAt(idx, '1'); + } + } + operations++; + } + return operations; + } +} diff --git a/Medium/Number of Subarrays with Bounded Maximum.java b/Medium/Number of Subarrays with Bounded Maximum.java new file mode 100644 index 00000000..a8c71df3 --- /dev/null +++ b/Medium/Number of Subarrays with Bounded Maximum.java @@ -0,0 +1,15 @@ +class Solution { + public int numSubarrayBoundedMax(int[] nums, int left, int right) { + return countHelper(nums, right) - countHelper(nums, left - 1); + } + + private int countHelper(int[] nums, int bound) { + int count = 0; + int curr = 0; + for (int num : nums) { + curr = num <= bound ? curr + 1 : 0; + count += curr; + } + return count; + } +} diff --git a/Medium/Number of Subsequences That Satisfy the Given Sum Condition.java b/Medium/Number of Subsequences That Satisfy the Given Sum Condition.java new file mode 100644 index 00000000..9a40ee6b --- /dev/null +++ b/Medium/Number of Subsequences That Satisfy the Given Sum Condition.java @@ -0,0 +1,26 @@ +class Solution { + + private static final int MOD = 1000_000_007; + + public int numSubseq(int[] nums, int target) { + int n = nums.length; + Arrays.sort(nums); + int[] power = new int[n]; + power[0] = 1; + for (int i = 1; i < n; i++) { + power[i] = (power[i - 1] * 2) % MOD; + } + int result = 0; + int left = 0; + int right = n - 1; + while (left <= right) { + if (nums[left] + nums[right] <= target) { + result = (result + power[right - left]) % MOD; + left++; + } else { + right--; + } + } + return result; + } +} diff --git a/Medium/Number of Ways to Split Array.java b/Medium/Number of Ways to Split Array.java new file mode 100644 index 00000000..3cbaed3a --- /dev/null +++ b/Medium/Number of Ways to Split Array.java @@ -0,0 +1,17 @@ +class Solution { + public int waysToSplitArray(int[] nums) { + long arraySum = 0; + for (int i = 0; i < nums.length; i++) { + arraySum += nums[i]; + } + int ways = 0; + long prefixSum = 0; + for (int i = 0; i < nums.length - 1; i++) { + prefixSum += nums[i]; + if (prefixSum >= arraySum - prefixSum) { + ways++; + } + } + return ways; + } +} diff --git a/Medium/Number of Zero-Filled Subarrays.java b/Medium/Number of Zero-Filled Subarrays.java new file mode 100644 index 00000000..b7c17309 --- /dev/null +++ b/Medium/Number of Zero-Filled Subarrays.java @@ -0,0 +1,16 @@ +class Solution { + public long zeroFilledSubarray(int[] nums) { + long subarrayCount = 0L; + int idx = 0; + while (idx < nums.length) { + long count = 0L; + while (idx < nums.length && nums[idx] == 0) { + idx++; + count++; + } + subarrayCount += (count * (count + 1)) / 2; + idx++; + } + return subarrayCount; + } +} diff --git a/Medium/Numbers With Same Consecutive Differences.java b/Medium/Numbers With Same Consecutive Differences.java index 24c35555..9c93c383 100644 --- a/Medium/Numbers With Same Consecutive Differences.java +++ b/Medium/Numbers With Same Consecutive Differences.java @@ -1,31 +1,25 @@ class Solution { - public int[] numsSameConsecDiff(int N, int K) { - if (N == 1) { - return new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - } - Set set = new HashSet<>(); - for (int i = 1; i <= 9; i++) { - helper(i, new StringBuilder(), K, set, N); - } - int[] ans = new int[set.size()]; - Iterator iterator = set.iterator(); - for (int i = 0; i < ans.length; i++) { - ans[i] = iterator.next(); - } - return ans; + public int[] numsSameConsecDiff(int n, int k) { + List result = new ArrayList<>(); + helper(n, k, result, new StringBuilder()); + return result.stream().mapToInt(Integer::intValue).toArray(); } - private void helper(int curr, StringBuilder sb, int k, Set set, int n) { + private void helper(int n, int k, List result, StringBuilder sb) { if (sb.length() == n) { - set.add(Integer.parseInt(sb.toString())); - } - if (sb.length() > n || curr > 9 || curr < 0) { + result.add(Integer.parseInt(sb.toString())); return; } - else { - sb.append(curr); - helper(curr + k, sb, k, set, n); - helper(curr - k, sb, k, set, n); + for (int i = 0; i <= 9; i++) { + if (sb.isEmpty() && i == 0) { + continue; + } + if (!sb.isEmpty() + && Math.abs(Character.getNumericValue(sb.charAt(sb.length() - 1)) - i) != k) { + continue; + } + sb.append(i); + helper(n, k, result, new StringBuilder(sb)); sb.deleteCharAt(sb.length() - 1); } } diff --git a/Medium/Odd Even Linked Lists.java b/Medium/Odd Even Linked Lists.java index 4c4a1aae..2c8adf87 100644 --- a/Medium/Odd Even Linked Lists.java +++ b/Medium/Odd Even Linked Lists.java @@ -3,23 +3,26 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { - public ListNode oddEvenList(ListNode head) { - if(head == null || head.next == null) - return head; - ListNode odd = head; - ListNode even = head.next; - ListNode evenHead = even; - while(odd.next != null && even.next != null){ - odd.next = even.next; - odd = odd.next; - even.next = odd.next; - even = even.next; - } - odd.next = evenHead; - return head; + public ListNode oddEvenList(ListNode head) { + if (head == null || head.next == null) { + return head; } + ListNode oddIdxNode = head; + ListNode evenIdxNodeStart = head.next; + ListNode evenIdxNode = evenIdxNodeStart; + while (evenIdxNode != null && evenIdxNode.next != null) { + oddIdxNode.next = evenIdxNode.next; + oddIdxNode = oddIdxNode.next; + evenIdxNode.next = oddIdxNode.next; + evenIdxNode = evenIdxNode.next; + } + oddIdxNode.next = evenIdxNodeStart; + return head; + } } diff --git a/Medium/One Edit Distance.java b/Medium/One Edit Distance.java index 7a78e333..662a41d1 100644 --- a/Medium/One Edit Distance.java +++ b/Medium/One Edit Distance.java @@ -1,50 +1,28 @@ class Solution { - public static boolean isOneEditDistance(String s, String t) { - if (Math.abs(s.length() - t.length()) > 1) { + public boolean isOneEditDistance(String s, String t) { + int diff = Math.abs(s.length() - t.length()); + if (s.equals(t) || diff > 1) { return false; } - else if (s.length() - t.length() == 0) { - if (s.equals(t)) { - return false; - } - - boolean missed = false; - for (int i=0; i j) { - return false; + // Delete 1 character from t + if (s.substring(idx).equals(t.substring(idx + 1))) { + return true; } - i++; - continue; + return false; } - - i++; - j++; + idx++; } - return true; } } diff --git a/Medium/Ones and Zeroes.java b/Medium/Ones and Zeroes.java new file mode 100644 index 00000000..d4e6335f --- /dev/null +++ b/Medium/Ones and Zeroes.java @@ -0,0 +1,26 @@ +class Solution { + public int findMaxForm(String[] strs, int m, int n) { + int[][] dp = new int[m + 1][n + 1]; + for (String s : strs) { + int[] count = getCountForZeroAndOne(s); + for (int zeroes = m; zeroes >= count[0]; zeroes--) { + for (int ones = n; ones >= count[1]; ones--) { + dp[zeroes][ones] = Math.max(1 + dp[zeroes - count[0]][ones - count[1]], dp[zeroes][ones]); + } + } + } + return dp[m][n]; + } + + private int[] getCountForZeroAndOne(String s) { + int[] count = {0, 0}; + for (char c : s.toCharArray()) { + if (c == '0') { + count[0]++; + } else { + count[1]++; + } + } + return count; + } +} diff --git a/Medium/Online Election.java b/Medium/Online Election.java index 34bc11ad..50dfc559 100644 --- a/Medium/Online Election.java +++ b/Medium/Online Election.java @@ -1,44 +1,24 @@ class TopVotedCandidate { - List winners; + private TreeMap currWinner; + public TopVotedCandidate(int[] persons, int[] times) { - winners = new ArrayList<>(); - Map countMap = new HashMap<>(); - Map timeMap = new HashMap<>(); - int maxVotes = 0; + this.currWinner = new TreeMap<>(); + Map candidateToVotecount = new HashMap<>(); + int currWinningCandidate = -1; for (int i = 0; i < persons.length; i++) { - countMap.put(persons[i], countMap.getOrDefault(persons[i], 0) + 1); - timeMap.put(persons[i], times[i]); - if (countMap.get(persons[i]) >= maxVotes) { - winners.add(new Winner(times[i], persons[i])); - maxVotes = Math.max(maxVotes, countMap.get(persons[i])); + int person = persons[i]; + int newVoteCount = candidateToVotecount.getOrDefault(person, 0) + 1; + candidateToVotecount.put(person, newVoteCount); + if (currWinningCandidate == -1 || newVoteCount >= candidateToVotecount.get(currWinningCandidate)) { + currWinningCandidate = person; } + currWinner.put(times[i], currWinningCandidate); } } public int q(int t) { - return winners.get(binarySearchHelper(t)).val; - } - - private int binarySearchHelper(int target) { - int start = 0; - int end = winners.size() - 1; - int idx = 0; - while (start <= end) { - int mid = (start + end) / 2; - if (winners.get(mid).time == target) { - idx = mid; - break; - } - else if (winners.get(mid).time < target) { - idx = mid; - start = mid + 1; - } - else { - end = mid - 1; - } - } - return idx == winners.size() ? 0 : idx; + return this.currWinner.floorEntry(t).getValue(); } } @@ -47,13 +27,3 @@ else if (winners.get(mid).time < target) { * TopVotedCandidate obj = new TopVotedCandidate(persons, times); * int param_1 = obj.q(t); */ - -class Winner { - int time; - int val; - - public Winner(int time, int val) { - this.time = time; - this.val = val; - } -} diff --git a/Medium/Online Stock Span.java b/Medium/Online Stock Span.java index 9f30c4fd..ff50093d 100644 --- a/Medium/Online Stock Span.java +++ b/Medium/Online Stock Span.java @@ -1,21 +1,20 @@ class StockSpanner { - Stack stack; - Stack occurences; - public StockSpanner() { - stack = new Stack<>(); - occurences = new Stack<>(); - } - - public int next(int price) { - int count = 1; - while (!stack.isEmpty() && stack.peek() <= price) { - stack.pop(); - count += occurences.pop(); + + // Entry in stack is the current price and count of prices <= current price + private final Stack stack; + + public StockSpanner() { + this.stack = new Stack<>(); + } + + public int next(int price) { + int count = 1; + while (!stack.isEmpty() && stack.peek()[0] <= price) { + count += stack.pop()[1]; + } + stack.push(new int[]{price, count}); + return count; } - stack.push(price); - occurences.push(count); - return count; - } } /** diff --git a/Medium/Open The Lock.java b/Medium/Open The Lock.java index 926e8521..f692f0ba 100644 --- a/Medium/Open The Lock.java +++ b/Medium/Open The Lock.java @@ -1,40 +1,38 @@ class Solution { public int openLock(String[] deadends, String target) { Set deadEndSet = new HashSet<>(Arrays.asList(deadends)); - if (deadEndSet.contains(target) || deadEndSet.contains("0000")) { + String startingPoint = "0000"; + if (deadEndSet.contains(startingPoint)) { return -1; } Queue queue = new LinkedList<>(); - Set seen = new HashSet<>(); - queue.add("0000"); - seen.add("0000"); - int steps = 0; + Set visited = new HashSet<>(); + queue.add(startingPoint); + visited.add(startingPoint); + int attempts = 0; int[] rotations = {-1, 1}; while (!queue.isEmpty()) { int size = queue.size(); for (int i = 0; i < size; i++) { String removed = queue.remove(); if (removed.equals(target)) { - return steps; + return attempts; } if (deadEndSet.contains(removed)) { continue; } for (int j = 0; j < 4; j++) { for (int rotation : rotations) { - int changedVal = ((removed.charAt(j) - '0') + rotation + 10) % 10; - String newRotation = new StringBuilder() - .append(removed.substring(0,j)) .append(changedVal) - .append(removed.substring(j + 1)) - .toString(); - if (!seen.contains(newRotation)) { - seen.add(newRotation); + int newValue = ((removed.charAt(j) - '0') + rotation + 10) % 10; + String newRotation = removed.substring(0, j) + newValue + removed.substring(j + 1); + if (!visited.contains(newRotation)) { + visited.add(newRotation); queue.add(newRotation); } } } } - steps++; + attempts++; } return -1; } diff --git a/Medium/Optimal Partition of String.java b/Medium/Optimal Partition of String.java new file mode 100644 index 00000000..68b01d59 --- /dev/null +++ b/Medium/Optimal Partition of String.java @@ -0,0 +1,14 @@ +class Solution { + public int partitionString(String s) { + int count = 0; + int idx = 0; + while (idx < s.length()) { + Set set = new HashSet<>(); + while (idx < s.length() && set.add(s.charAt(idx))) { + idx++; + } + count++; + } + return count; + } +} diff --git a/Medium/Out of Boundary Paths.java b/Medium/Out of Boundary Paths.java new file mode 100644 index 00000000..fc7e9a26 --- /dev/null +++ b/Medium/Out of Boundary Paths.java @@ -0,0 +1,26 @@ +class Solution { + + private static final int MOD = 1000_000_007; + + public int findPaths(int m, int n, int maxMove, int startRow, int startColumn) { + Integer[][][] dp = new Integer[m][n][maxMove + 1]; + return findPaths(m, n, maxMove, startRow, startColumn, dp); + } + + public int findPaths(int m, int n, int maxMove, int startRow, int startColumn, Integer[][][] dp) { + if (startRow == m || startColumn == n || startRow < 0 || startColumn < 0) { + return 1; + } + if (maxMove == 0) { + return 0; + } + if (dp[startRow][startColumn][maxMove] != null) { + return dp[startRow][startColumn][maxMove]; + } + return dp[startRow][startColumn][maxMove] = ( + (findPaths(m, n, maxMove - 1, startRow - 1, startColumn, dp) + + findPaths(m, n, maxMove - 1, startRow + 1, startColumn, dp)) % MOD + + (findPaths(m, n, maxMove - 1, startRow, startColumn - 1, dp) + + findPaths(m, n, maxMove - 1, startRow, startColumn + 1, dp)) % MOD) % MOD; + } +} diff --git a/Medium/Pacific Atlantic Water Flow.java b/Medium/Pacific Atlantic Water Flow.java new file mode 100644 index 00000000..3c129529 --- /dev/null +++ b/Medium/Pacific Atlantic Water Flow.java @@ -0,0 +1,52 @@ +class Solution { + private final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + + public List> pacificAtlantic(int[][] heights) { + int numRows = heights.length; + int numCols = heights[0].length; + Queue pacificQueue = new LinkedList<>(); + Queue atlanticQueue = new LinkedList<>(); + for (int i = 0; i < numRows; i++) { + pacificQueue.add(new int[]{i, 0}); + atlanticQueue.add(new int[]{i, numCols - 1}); + } + for (int i = 0; i < numCols; i++) { + pacificQueue.add(new int[]{0, i}); + atlanticQueue.add(new int[]{numRows - 1, i}); + } + boolean[][] pacificReachable = bfs(pacificQueue, heights); + boolean[][] atlanticReachable = bfs(atlanticQueue, heights); + List> result = new ArrayList<>(); + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numCols; j++) { + if (pacificReachable[i][j] && atlanticReachable[i][j]) { + result.add(Arrays.asList(i, j)); + } + } + } + return result; + } + + private boolean[][] bfs(Queue queue, int[][] heights) { + int numRows = heights.length; + int numCols = heights[0].length; + boolean[][] reachable = new boolean[numRows][numCols]; + while (!queue.isEmpty()) { + int[] removed = queue.remove(); + int x = removed[0]; + int y = removed[1]; + reachable[x][y] = true; + for (int[] dir : DIRS) { + int newX = x + dir[0]; + int newY = y + dir[1]; + if (newX < 0 || newY < 0 || newX >= numRows || newY >= numCols || reachable[newX][newY]) { + continue; + } + if (heights[newX][newY] >= heights[x][y]) { + queue.add(new int[]{newX, newY}); + } + } + } + return reachable; + } +} diff --git a/Medium/Paint Fence.java b/Medium/Paint Fence.java new file mode 100644 index 00000000..39c72ffa --- /dev/null +++ b/Medium/Paint Fence.java @@ -0,0 +1,20 @@ +class Solution { + public int numWays(int n, int k) { + Map map = new HashMap<>(); + return numWays(n, k, map); + } + + private int numWays(int n, int k, Map map) { + if (n == 1) { + return k; + } + if (n == 2) { + return k * k; + } + if (map.containsKey(n)) { + return map.get(n); + } + map.put(n, (k - 1) * (numWays(n - 1, k, map) + numWays(n - 2, k, map))); + return map.get(n); + } +} diff --git a/Medium/Paint House.java b/Medium/Paint House.java new file mode 100644 index 00000000..27b1a502 --- /dev/null +++ b/Medium/Paint House.java @@ -0,0 +1,15 @@ +class Solution { + public int minCost(int[][] costs) { + int n = costs.length; + int[][] dp = new int[n][3]; + dp[0][0] = costs[0][0]; + dp[0][1] = costs[0][1]; + dp[0][2] = costs[0][2]; + for (int i = 1; i < n; i++) { + dp[i][0] = Math.min(dp[i - 1][1], dp[i - 1][2]) + costs[i][0]; + dp[i][1] = Math.min(dp[i - 1][0], dp[i - 1][2]) + costs[i][1]; + dp[i][2] = Math.min(dp[i - 1][0], dp[i - 1][1]) + costs[i][2]; + } + return Math.min(dp[n - 1][0], Math.min(dp[n - 1][1], dp[n - 1][2])); + } +} diff --git a/Medium/Palindrome Partitioning.java b/Medium/Palindrome Partitioning.java index 1171f009..de89ed16 100644 --- a/Medium/Palindrome Partitioning.java +++ b/Medium/Palindrome Partitioning.java @@ -1,27 +1,31 @@ class Solution { - public List> partition(String a) { - List> ans = new ArrayList<>(); - helper(ans, new ArrayList(), a, 0); - return ans; + public List> partition(String s) { + List> result = new ArrayList<>(); + backtrack(result, new ArrayList<>(), s, 0); + return result; } - - private void helper(List> ans, List temp, String a, int idx) { - if (idx == a.length()) { - ans.add(new ArrayList<>(temp)); + + private void backtrack(List> result, List currentList, + String s, int idx) { + if (idx == s.length()) { + result.add(new ArrayList<>(currentList)); return; } - for (int i=idx; i= 0 && right < N && s.charAt(left) == s.charAt(right)) { - ans++; - left--; - right++; - } + int[] palindromeCount = {0}; + for (int i = 0; i < s.length(); i++) { + checkPalindrome(s, i, i, palindromeCount); + checkPalindrome(s, i, i + 1, palindromeCount); + } + return palindromeCount[0]; + } + + private void checkPalindrome(String s, int leftIdx, int rightIdx, int[] palindromeCount) { + while (leftIdx >= 0 && rightIdx < s.length() && s.charAt(leftIdx) == s.charAt(rightIdx)) { + palindromeCount[0]++; + leftIdx--; + rightIdx++; } - return ans; } } diff --git a/Medium/Pancake Sorting.java b/Medium/Pancake Sorting.java index a390ceb2..b8606b27 100644 --- a/Medium/Pancake Sorting.java +++ b/Medium/Pancake Sorting.java @@ -1,41 +1,34 @@ class Solution { - public List pancakeSort(int[] A) { - List ans = new ArrayList<>(); - int[] copy = Arrays.copyOf(A, A.length); - int n = A.length - 1; - Arrays.sort(A); - int greatest = A.length - 1; - for (int i = 0; i < A.length; i++) { - int idx = findIdx(copy, A[greatest]); - flip(copy, idx); - ans.add(idx + 1); - flip(copy, greatest); - ans.add(greatest + 1); - greatest--; + public List pancakeSort(int[] arr) { + List result = new ArrayList<>(); + for (int i = arr.length; i > 0; i--) { + int idx = findIdx(arr, i); + if (idx != i - 1) { + if (idx != 0) { + result.add(idx + 1); + flip(arr, idx + 1); } - - return ans; + result.add(i); + flip(arr, i); + } } - - private void flip (int[] copy, int idx) { - int start = 0; - int end = idx; - while (start < end) { - int temp = copy[start]; - copy[start] = copy[end]; - copy[end] = temp; - start++; - end--; - } + return result; + } + + private void flip(int[] arr, int k) { + for (int i = 0; i < k / 2; i++) { + int temp = arr[i]; + arr[i] = arr[k - i - 1]; + arr[k - i - 1] = temp; } - - private int findIdx (int[] arr, int target) { - for (int i = 0; i < arr.length; i++) { - if (arr[i] == target) { - return i; - } - } - - return -1; + } + + private int findIdx(int[] arr, int target) { + for (int i = 0; i < arr.length; i++) { + if (arr[i] == target) { + return i; + } } + return -1; + } } diff --git a/Medium/Parallel Courses.java b/Medium/Parallel Courses.java new file mode 100644 index 00000000..797e3b58 --- /dev/null +++ b/Medium/Parallel Courses.java @@ -0,0 +1,35 @@ +class Solution { + public int minimumSemesters(int n, int[][] relations) { + Map> graph = new HashMap<>(); + int[] indegree = new int[n]; + for (int[] relation : relations) { + int course = relation[0]; + int dependency = relation[1]; + indegree[course - 1]++; + graph.computeIfAbsent(dependency, k -> new HashSet<>()).add(course); + } + Queue queue = new LinkedList<>(); + int numOfSemesters = 0; + int coursesTaken = 0; + for (int i = 0; i < n; i++) { + if (indegree[i] == 0) { + queue.add(i + 1); + } + } + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + int removed = queue.remove(); + coursesTaken++; + for (Integer dependent : graph.getOrDefault(removed, new HashSet<>())) { + indegree[dependent - 1]--; + if (indegree[dependent - 1] == 0) { + queue.add(dependent); + } + } + } + numOfSemesters++; + } + return coursesTaken == n ? numOfSemesters : -1; + } +} diff --git a/Medium/Partition Array According to Given Pivot.java b/Medium/Partition Array According to Given Pivot.java new file mode 100644 index 00000000..740b1707 --- /dev/null +++ b/Medium/Partition Array According to Given Pivot.java @@ -0,0 +1,20 @@ +class Solution { + public int[] pivotArray(int[] nums, int pivot) { + int[] result = new int[nums.length]; + int leftIdx = 0; + int rightIdx = nums.length - 1; + for (int i = 0; i < nums.length; i++) { + if (nums[i] < pivot) { + result[leftIdx++] = nums[i]; + } + int tempIdx = nums.length - 1 - i; + if (nums[tempIdx] > pivot) { + result[rightIdx--] = nums[tempIdx]; + } + } + while (leftIdx <= rightIdx) { + result[leftIdx++] = pivot; + } + return result; + } +} diff --git a/Medium/Partition Array for Maximum Sum.java b/Medium/Partition Array for Maximum Sum.java new file mode 100644 index 00000000..4868c1c3 --- /dev/null +++ b/Medium/Partition Array for Maximum Sum.java @@ -0,0 +1,25 @@ +class Solution { + public int maxSumAfterPartitioning(int[] arr, int k) { + Integer[] dp = new Integer[arr.length]; + return maxSum(arr, k, dp, 0); + } + + private int maxSum(int[] arr, int k, Integer[] dp, int start) { + int n = arr.length; + if (start >= n) { + return 0; + } + if (dp[start] != null) { + return dp[start]; + } + int currMax = 0; + int result = 0; + int end = Math.min(n, start + k); + for (int i = start; i < end; i++) { + currMax = Math.max(currMax, arr[i]); + result = Math.max(result, + currMax * (i - start + 1) + maxSum(arr, k, dp, i + 1)); + } + return dp[start] = result; + } +} diff --git a/Medium/Partition Equal Subset Sum.java b/Medium/Partition Equal Subset Sum.java new file mode 100644 index 00000000..41c71f7e --- /dev/null +++ b/Medium/Partition Equal Subset Sum.java @@ -0,0 +1,23 @@ +class Solution { + public boolean canPartition(int[] nums) { + int sum = 0; + for (int num : nums) { + sum += num; + } + if (sum % 2 == 1) { + return false; + } + sum /= 2; + int n = nums.length; + boolean[] dp = new boolean[sum + 1]; + dp[0] = true; + for (int num : nums) { + for (int i = sum; i > 0; i--) { + if (i >= num) { + dp[i] = dp[i] || dp[i - num]; + } + } + } + return dp[sum]; + } +} diff --git a/Medium/Partition Labels.java b/Medium/Partition Labels.java index c407b224..e3157703 100644 --- a/Medium/Partition Labels.java +++ b/Medium/Partition Labels.java @@ -1,22 +1,19 @@ class Solution { - public List partitionLabels(String S) { - if (S == null || S.length() == 0) { - return new ArrayList<>(); + public List partitionLabels(String s) { + Map map = new HashMap<>(); + for (int i = 0; i < s.length(); i++) { + map.put(s.charAt(i), i); + } + List result = new ArrayList<>(); + int start = 0; + int maxIdx = Integer.MIN_VALUE; + for (int i = 0; i < s.length(); i++) { + maxIdx = Math.max(map.get(s.charAt(i)), maxIdx); + if (maxIdx == i) { + result.add(i - start + 1); + start = i + 1; + } + } + return result; } - int[] count = new int[26]; - for (int i = 0; i < S.length(); i++) { - count[S.charAt(i) - 'a'] = i; - } - int start = -1; - int end = 0; - List list = new ArrayList<>(); - for (int i = 0; i < S.length(); i++) { - end = Math.max(end, count[S.charAt(i) - 'a']); - if (end == i) { - list.add(end - start); - start = end; - } - } - return list; - } } diff --git a/Medium/Partition List.java b/Medium/Partition List.java index 400a58f4..a807608c 100644 --- a/Medium/Partition List.java +++ b/Medium/Partition List.java @@ -3,35 +3,41 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode partition(ListNode head, int x) { - Queue small = new LinkedList<>(); - Queue bigOrEqual = new LinkedList<>(); - ListNode curr = head; - while (curr != null){ - if (curr.val < x) { - small.add(curr.val); + ListNode lessHead = null; + ListNode lessCurr = null; + ListNode greaterHead = null; + ListNode greaterCurr = null; + while (head != null) { + if (head.val < x) { + if (lessCurr == null) { + lessCurr = new ListNode(head.val); + lessHead = lessCurr; + } else { + lessCurr.next = new ListNode(head.val); + lessCurr = lessCurr.next; + } + } else { + if (greaterCurr == null) { + greaterCurr = new ListNode(head.val); + greaterHead = greaterCurr; + } else { + greaterCurr.next = new ListNode(head.val); + greaterCurr = greaterCurr.next; + } } - else { - bigOrEqual.add(curr.val); - } - curr = curr.next; + head = head.next; } - - curr = head; - while (curr != null) { - if (!small.isEmpty()) { - curr.val = small.remove(); - } - else { - curr.val = bigOrEqual.remove(); - } - curr = curr.next; + if (lessHead == null) { + return greaterHead; } - - return head; + lessCurr.next = greaterHead; + return lessHead; } } diff --git a/Medium/Partitioning Into Minimum Number Of Deci-Binary Numbers.java b/Medium/Partitioning Into Minimum Number Of Deci-Binary Numbers.java new file mode 100644 index 00000000..4bd5953a --- /dev/null +++ b/Medium/Partitioning Into Minimum Number Of Deci-Binary Numbers.java @@ -0,0 +1,9 @@ +class Solution { + public int minPartitions(String n) { + int maxDigit = Character.getNumericValue(n.charAt(0)); + for (char c : n.toCharArray()) { + maxDigit = Math.max(maxDigit, Character.getNumericValue(c)); + } + return maxDigit; + } +} diff --git a/Medium/Path Sum II.java b/Medium/Path Sum II.java index e90b2004..776676f7 100644 --- a/Medium/Path Sum II.java +++ b/Medium/Path Sum II.java @@ -4,36 +4,67 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - List> list = new ArrayList<>(); - public List> pathSum(TreeNode root, int sum) { - if (root == null) return list; - - Stack path = new Stack<>(); - - pathSumImpl(root, sum, path); - return list; + public List> pathSum(TreeNode root, int targetSum) { + List> result = new ArrayList<>(); + if (root == null) { + return result; } - - private void pathSumImpl(TreeNode root, int sum, Stack path) { - path.push(root.val); - if (root.left == null && root.right == null) { - if (sum == root.val) { - list.add(new ArrayList(path)); - } - } - - if (root.left != null) { - pathSumImpl(root.left, sum-root.val, path); + Queue queue = new LinkedList<>(); + NodePathSumWrapper currNode = new NodePathSumWrapper(root, 0); + currNode.addToPath(root.val); + queue.add(currNode); + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + NodePathSumWrapper removed = queue.remove(); + TreeNode node = removed.node; + if (node.left == null && node.right == null) { + if (removed.currSum == targetSum) { + result.add(new ArrayList<>(removed.path)); + } + } else { + if (node.left != null) { + NodePathSumWrapper leftNodeWrapper = new NodePathSumWrapper(node.left, removed.currSum); + leftNodeWrapper.path.addAll(removed.path); + leftNodeWrapper.addToPath(node.left.val); + queue.add(leftNodeWrapper); + } + if (node.right != null) { + NodePathSumWrapper rightNodeWrapper = new NodePathSumWrapper(node.right, removed.currSum); + rightNodeWrapper.path.addAll(removed.path); + rightNodeWrapper.addToPath(node.right.val); + queue.add(rightNodeWrapper); + } } - - if (root.right != null) { - pathSumImpl(root.right, sum-root.val, path); - } - - path.pop(); + } + } + return result; + } + + private static class NodePathSumWrapper { + TreeNode node; + int currSum; + List path; + + public NodePathSumWrapper(TreeNode node, int currSum) { + this.node = node; + this.currSum = currSum; + this.path = new ArrayList<>(); + } + + public void addToPath(int value) { + this.path.add(value); + this.currSum += value; } + } } diff --git a/Medium/Path Sum III.java b/Medium/Path Sum III.java new file mode 100644 index 00000000..69badada --- /dev/null +++ b/Medium/Path Sum III.java @@ -0,0 +1,36 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public int pathSum(TreeNode root, int targetSum) { + Map map = new HashMap<>(); + map.put(0L, 1); + int[] count = {0}; + preorder(root, 0L, map, count, targetSum); + return count[0]; + } + + private void preorder(TreeNode root, long currSum, Map map, int[] count, int targetSum) { + if (root == null) { + return; + } + currSum += root.val; + count[0] += map.getOrDefault(currSum - targetSum, 0); + map.put(currSum, map.getOrDefault(currSum, 0) + 1); + preorder(root.left, currSum, map, count, targetSum); + preorder(root.right, currSum, map, count, targetSum); + map.put(currSum, map.get(currSum) - 1); + } +} diff --git a/Medium/Path With Maximum Minimum Value.java b/Medium/Path With Maximum Minimum Value.java index d2204779..31942850 100644 --- a/Medium/Path With Maximum Minimum Value.java +++ b/Medium/Path With Maximum Minimum Value.java @@ -1,34 +1,27 @@ class Solution { - int[][] dirs = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; - public int maximumMinimumPath(int[][] A) { - int rows = A.length; - int cols = A[0].length; - boolean[][] visited = new boolean[rows][cols]; - PriorityQueue pq = new PriorityQueue<>(new Comparator(){ - public int compare(int[] p1, int[] p2) { - return p2[0] - p1[0]; - } - }); - int maxVal = A[0][0]; - pq.add(new int[]{A[0][0], 0, 0}); - visited[0][0] = true; + + private static final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + + public int maximumMinimumPath(int[][] grid) { + PriorityQueue pq = new PriorityQueue<>((o1, o2) -> o2[2] - o1[2]); + pq.add(new int[]{0, 0, grid[0][0]}); + int numRows = grid.length; + int numCols = grid[0].length; + boolean[][] visited = new boolean[numRows][numCols]; while (!pq.isEmpty()) { int[] removed = pq.poll(); - int x = removed[1]; - int y = removed[2]; - maxVal = Math.min(maxVal, removed[0]); - if (x == rows - 1 && y == cols - 1) { - break; + if (removed[0] == numRows - 1 && removed[1] == numCols - 1) { + return removed[2]; } - for (int[] dir : dirs) { - int newX = x + dir[0]; - int newY = y + dir[1]; - if (newX >= 0 && newY >= 0 && newX < rows && newY < cols && !visited[newX][newY]) { - pq.add(new int[]{A[newX][newY], newX, newY}); - visited[newX][newY] = true; + visited[removed[0]][removed[1]] = true; + for (int[] dir : DIRS) { + int newX = removed[0] + dir[0]; + int newY = removed[1] + dir[1]; + if (newX >= 0 && newY >= 0 && newX < numRows && newY < numCols && !visited[newX][newY]) { + pq.add(new int[]{newX, newY, Math.min(removed[2], grid[newX][newY])}); } } } - return maxVal; + return -1; } } diff --git a/Medium/Path With Minimum Effort.java b/Medium/Path With Minimum Effort.java new file mode 100644 index 00000000..b9c33606 --- /dev/null +++ b/Medium/Path With Minimum Effort.java @@ -0,0 +1,47 @@ +class Solution { + + private final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + + public int minimumEffortPath(int[][] heights) { + if (heights.length == 1 && heights[0].length == 1) { + return 0; + } + int leftBound = 0; + int rightBound = 1000000; + while (leftBound < rightBound) { + int mid = (leftBound + rightBound) / 2; + if (connected(heights, mid)) { + rightBound = mid; + } else { + leftBound = mid + 1; + } + } + return leftBound; + } + + private boolean connected(int[][] heights, int targetEffort) { + int numRows = heights.length; + int numCols = heights[0].length; + Queue queue = new LinkedList<>(); + boolean[][] seen = new boolean[numRows][numCols]; + queue.add(new int[]{0, 0}); + seen[0][0] = true; + while (!queue.isEmpty()) { + int[] removed = queue.remove(); + int x = removed[0]; + int y = removed[1]; + if (x == numRows - 1 && y == numCols - 1) { + return true; + } + for (int[] dir : DIRS) { + int newX = x + dir[0]; + int newY = y + dir[1]; + if (newX >= 0 && newY >= 0 && newX < numRows && newY < numCols && !seen[newX][newY] && Math.abs(heights[x][y] - heights[newX][newY]) <= targetEffort) { + queue.add(new int[]{newX, newY}); + seen[newX][newY] = true; + } + } + } + return false; + } +} diff --git a/Medium/Peak Index in a Mountain Array.java b/Medium/Peak Index in a Mountain Array.java new file mode 100644 index 00000000..d496f7c4 --- /dev/null +++ b/Medium/Peak Index in a Mountain Array.java @@ -0,0 +1,15 @@ +class Solution { + public int peakIndexInMountainArray(int[] arr) { + int start = 0; + int end = arr.length - 1; + while (start < end) { + int mid = (start + end) / 2; + if (arr[mid] < arr[mid + 1]) { + start = mid + 1; + } else { + end = mid; + } + } + return start; + } +} diff --git a/Medium/Peeking Iterator.java b/Medium/Peeking Iterator.java index 44edad63..4a1c6782 100644 --- a/Medium/Peeking Iterator.java +++ b/Medium/Peeking Iterator.java @@ -1,47 +1,36 @@ // Java Iterator interface reference: // https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html -import java.util.NoSuchElementException; class PeekingIterator implements Iterator { + private Iterator iterator; + private Integer topElement; - private Integer next; - private Iterator iter; - private boolean noNextElement = false; - - public PeekingIterator(Iterator iterator) { - // initialize any member here. - iter = iterator; - moveIterator(); - } + public PeekingIterator(Iterator iterator) { + // initialize any member here. + this.iterator = iterator; + populateTopElement(); + } - // Returns the next element in the iteration without advancing the iterator. - public Integer peek() { - return next; - } + // Returns the next element in the iteration without advancing the iterator. + public Integer peek() { + return this.topElement; + } - // hasNext() and next() should behave the same as in the Iterator interface. - // Override them if needed. - @Override - public Integer next() { - if (noNextElement) { - throw new NoSuchElementException(); - } - Integer val = next; - moveIterator(); - return val; - } + // hasNext() and next() should behave the same as in the Iterator interface. + // Override them if needed. + @Override + public Integer next() { + Integer nextValue = this.topElement; + populateTopElement(); + return nextValue; + } - @Override - public boolean hasNext() { - return !noNextElement; - } - - public void moveIterator() { - if (iter.hasNext()) { - next = iter.next(); - } - else { - noNextElement = true; - } - } + @Override + public boolean hasNext() { + return this.topElement != null; + } + + private void populateTopElement() { + this.topElement = this.iterator.hasNext() ? this.iterator.next() : null; + } } diff --git a/Medium/Perfect Squares.java b/Medium/Perfect Squares.java index f0b9fb81..4f61d351 100644 --- a/Medium/Perfect Squares.java +++ b/Medium/Perfect Squares.java @@ -1,28 +1,15 @@ class Solution { - Set squareNums; public int numSquares(int n) { - squareNums = new HashSet<>(); - for (int i = 1; i * i <= n; i++) { - squareNums.add(i * i); - } - int count = 1; - for (count = 1; count <= n; count++) { - if (isDividedBy(n, count)) { - return count; - } - } - return count; - } - - private boolean isDividedBy(int n, int count) { - if (count == 1) { - return squareNums.contains(n); - } - for (Integer squareNum : squareNums) { - if (isDividedBy(n - squareNum, count - 1)) { - return true; + int[] dp = new int[n + 1]; + Arrays.fill(dp, Integer.MAX_VALUE); + dp[0] = 0; + for(int i = 1; i <= n; i++) { + int min = Integer.MAX_VALUE; + for (int j = 1; i - j * j >= 0; j++) { + min = Math.min(min, dp[i - j * j] + 1); } + dp[i] = min; } - return false; + return dp[n]; } } diff --git a/Medium/Permutation in String.java b/Medium/Permutation in String.java index e405a988..dd255290 100644 --- a/Medium/Permutation in String.java +++ b/Medium/Permutation in String.java @@ -1,25 +1,38 @@ class Solution { - public boolean checkInclusion(String s1, String s2) { - if (s1.length() > s2.length()) { - return false; + public boolean checkInclusion(String s1, String s2) { + if (s1.length() > s2.length()) { + return false; + } + Map map = new HashMap<>(); + for (char c : s1.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); + } + int n = s1.length(); + int[] count = {map.size()}; + for (int i = 0; i < n - 1; i++) { + updateMap(map, s2.charAt(i), count, true); + } + int start = 0; + for (int i = n - 1; i < s2.length(); i++) { + updateMap(map, s2.charAt(i), count, true); + if (count[0] == 0) { + return true; + } + updateMap(map, s2.charAt(start++), count, false); + } + return false; } - int[] counter = new int[26]; - for (char c : s1.toCharArray()) { - counter[c - 'a']++; + + private void updateMap(Map map, char c, int[] count, boolean decrement) { + if (map.containsKey(c)) { + int diff = decrement ? -1 : 1; + map.put(c, map.get(c) + diff); + if (decrement && map.get(c) == 0) { + count[0]--; + } + if (!decrement && map.get(c) == 1) { + count[0]++; + } + } } - String targetStr = Arrays.toString(counter); - int[] targetCounter = new int[26]; - for (int i = 0; i < s1.length() - 1; i++) { - targetCounter[s2.charAt(i) - 'a']++; - } - int start = 0; - for (int i = s1.length() - 1; i < s2.length(); i++) { - targetCounter[s2.charAt(i) - 'a']++; - if (Arrays.toString(targetCounter).equals(targetStr)) { - return true; - } - targetCounter[s2.charAt(start++) - 'a']--; - } - return false; - } } diff --git a/Medium/Permutations II.java b/Medium/Permutations II.java index 79757bf3..2469a285 100644 --- a/Medium/Permutations II.java +++ b/Medium/Permutations II.java @@ -1,34 +1,25 @@ class Solution { public List> permuteUnique(int[] nums) { - List> ans = new ArrayList<>(); - if (nums.length == 0) { - return ans; - } - List curr = new ArrayList<>(); + List> result = new ArrayList<>(); Arrays.sort(nums); - helper(nums, ans, curr, new boolean[nums.length]); - return ans; + helper(nums, result, new ArrayList<>(), new boolean[nums.length]); + return result; } - - private void helper(int[] nums, List> ans, List curr, boolean[] used) { + + private void helper(int[] nums, List> result, List curr, boolean[] visited) { if (curr.size() == nums.length) { - ans.add(new ArrayList<>(curr)); + result.add(new ArrayList<>(curr)); + return; } - else { - for (int i = 0; i < nums.length; i++) { - if (used[i]) { - continue; - } - if (i > 0 && nums[i - 1] == nums[i] && !used[i - 1]) { - continue; - } - used[i] = true; - curr.add(nums[i]); - helper(nums, ans, curr, used); - curr.remove(curr.size() - 1); - used[i] = false; + for (int i = 0; i < nums.length; i++) { + if (visited[i] || (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1])) { + continue; } + curr.add(nums[i]); + visited[i] = true; + helper(nums, result, curr, visited); + curr.remove(curr.size() - 1); + visited[i] = false; } } } - diff --git a/Medium/Permutations.java b/Medium/Permutations.java index f09beb5e..61c86f42 100644 --- a/Medium/Permutations.java +++ b/Medium/Permutations.java @@ -1,26 +1,25 @@ class Solution { - public List> permute(int[] nums) { - List> ans = new ArrayList <>(); - Set used = new HashSet <>(); - permuteHelper(nums, nums.length, ans, used, new ArrayList<>()); - return ans; - } - - private void permuteHelper(int[] nums, int length, List> ans, - Set used, ArrayList curr) { - if (curr.size() == length) { - ans.add(new ArrayList <>(curr)); - return; + public List> permute(int[] nums) { + List> result = new ArrayList<>(); + Set visited = new HashSet<>(); + permute(nums, result, new ArrayList<>(), visited); + return result; } - - for (int i = 0; i < length; i++) { - if (!used.contains(nums[i])) { - used.add(nums[i]); - curr.add(nums[i]); - permuteHelper(nums, length, ans, used, curr); - used.remove(nums[i]); - curr.remove(curr.size() - 1); - } + + private void permute(int[] nums, List> result, List curr, Set visited) { + if (curr.size() == nums.length) { + result.add(new ArrayList<>(curr)); + return; + } + for (int i = 0; i < nums.length; i++) { + if (visited.contains(nums[i])) { + continue; + } + visited.add(nums[i]); + curr.add(nums[i]); + permute(nums, result, curr, visited); + visited.remove(nums[i]); + curr.remove(curr.size() - 1); + } } - } } diff --git a/Medium/Populating Next Right Pointers in Each Node II.java b/Medium/Populating Next Right Pointers in Each Node II.java index 96dd48fc..42c9e387 100644 --- a/Medium/Populating Next Right Pointers in Each Node II.java +++ b/Medium/Populating Next Right Pointers in Each Node II.java @@ -23,13 +23,10 @@ public Node(int _val, Node _left, Node _right, Node _next) { class Solution { public Node connect(Node root) { - if (root == null) { - return null; - } Queue queue = new LinkedList<>(); queue.add(root); queue.add(null); - while (!queue.isEmpty() && queue.peek() != null) { + while (queue.peek() != null) { int size = queue.size() - 1; while (size-- > 0) { Node removed = queue.remove(); diff --git a/Medium/Populating Next Right Pointers in Each Node.java b/Medium/Populating Next Right Pointers in Each Node.java new file mode 100644 index 00000000..176deb77 --- /dev/null +++ b/Medium/Populating Next Right Pointers in Each Node.java @@ -0,0 +1,41 @@ +/* +// Definition for a Node. +class Node { + public int val; + public Node left; + public Node right; + public Node next; + + public Node() {} + + public Node(int _val) { + val = _val; + } + + public Node(int _val, Node _left, Node _right, Node _next) { + val = _val; + left = _left; + right = _right; + next = _next; + } +}; +*/ + +class Solution { + public Node connect(Node root) { + Node prev = root; + Node curr = null; + while (prev != null && prev.left != null) { + curr = prev; + while (curr != null) { + curr.left.next = curr.right; + if (curr.next != null) { + curr.right.next = curr.next.left; + } + curr = curr.next; + } + prev = prev.left; + } + return root; + } +} diff --git a/Medium/Possible Bipartition.java b/Medium/Possible Bipartition.java new file mode 100644 index 00000000..4d2a0500 --- /dev/null +++ b/Medium/Possible Bipartition.java @@ -0,0 +1,38 @@ +class Solution { + public boolean possibleBipartition(int n, int[][] dislikes) { + Map> map = new HashMap<>(); + for (int[] dislike : dislikes) { + map.computeIfAbsent(dislike[0], k -> new ArrayList<>()).add(dislike[1]); + map.computeIfAbsent(dislike[1], k -> new ArrayList<>()).add(dislike[0]); + } + int[] color = new int[n + 1]; + Arrays.fill(color, -1); + for (int i = 1; i <= n; i++) { + if (color[i] == -1) { + if (!bfs(i, map, color)) { + return false; + } + } + } + return true; + } + + private boolean bfs(int node, Map> map, int[] color) { + Queue queue = new LinkedList<>(); + queue.add(node); + color[node] = 0; + while (!queue.isEmpty()) { + int removed = queue.remove(); + for (Integer neighbor : map.getOrDefault(removed, new ArrayList<>())) { + if (color[neighbor] == color[removed]) { + return false; + } + if (color[neighbor] == -1) { + color[neighbor] = 1 - color[removed]; + queue.add(neighbor); + } + } + } + return true; + } +} diff --git a/Medium/Pow(x, n).java b/Medium/Pow(x, n).java new file mode 100644 index 00000000..541772af --- /dev/null +++ b/Medium/Pow(x, n).java @@ -0,0 +1,11 @@ +class Solution { + public double myPow(double x, int n) { + if (n == 0) { + return 1; + } + if (n < 0) { + return 1 / x * myPow(1 / x, -1 * (n + 1)); + } + return n % 2 == 0 ? myPow(x * x, n / 2) : x * myPow(x * x, n / 2); + } +} diff --git a/Medium/Print Immutable Linked List in Reverse.java b/Medium/Print Immutable Linked List in Reverse.java index 0ec55d3e..d571d18e 100644 --- a/Medium/Print Immutable Linked List in Reverse.java +++ b/Medium/Print Immutable Linked List in Reverse.java @@ -9,10 +9,13 @@ class Solution { public void printLinkedListInReverse(ImmutableListNode head) { - if (head == null) { - return; + Stack stack = new Stack<>(); + while (head != null) { + stack.push(head); + head = head.getNext(); + } + while (!stack.isEmpty()) { + stack.pop().printValue(); } - printLinkedListInReverse(head.getNext()); - head.printValue(); } } diff --git a/Medium/Product of Two Run-Length Encoded Arrays.java b/Medium/Product of Two Run-Length Encoded Arrays.java new file mode 100644 index 00000000..4aab9bc8 --- /dev/null +++ b/Medium/Product of Two Run-Length Encoded Arrays.java @@ -0,0 +1,31 @@ +class Solution { + public List> findRLEArray(int[][] encoded1, int[][] encoded2) { + int idxOne = 0; + int idxTwo = 0; + List> result = new ArrayList<>(); + while (idxOne < encoded1.length && idxTwo < encoded2.length) { + int valOne = encoded1[idxOne][0]; + int valTwo = encoded2[idxTwo][0]; + int countOne = encoded1[idxOne][1]; + int countTwo = encoded2[idxTwo][1]; + int value = valOne * valTwo; + int count = Math.min(countOne, countTwo); + encoded1[idxOne][1] -= count; + encoded2[idxTwo][1] -= count; + if (encoded1[idxOne][1] == 0) { + idxOne++; + } + if (encoded2[idxTwo][1] == 0) { + idxTwo++; + } + if (!result.isEmpty() && result.get(result.size() - 1).get(0) == value) { + int existingCount = result.get(result.size() - 1).get(1); + int newCount = existingCount + count; + result.get(result.size() - 1).set(1, newCount); + } else { + result.add(Arrays.asList(value, count)); + } + } + return result; + } +} diff --git a/Medium/Product of the Last K Numbers.java b/Medium/Product of the Last K Numbers.java index 9eda5d06..acfc5bae 100644 --- a/Medium/Product of the Last K Numbers.java +++ b/Medium/Product of the Last K Numbers.java @@ -1,21 +1,24 @@ class ProductOfNumbers { - List list; + + private List list; + public ProductOfNumbers() { + this.list = new ArrayList<>(); add(0); } public void add(int num) { if (num > 0) { list.add(list.get(list.size() - 1) * num); - } - else { + } else { list = new ArrayList<>(); list.add(1); } } public int getProduct(int k) { - return k < list.size() ? list.get(list.size() - 1) / list.get(list.size() - k - 1) : 0; + int n = list.size(); + return k < n ? list.get(n - 1) / list.get(n - k - 1) : 0; } } diff --git a/Medium/Pseudo-Palindromic Paths in a Binary Tree.java b/Medium/Pseudo-Palindromic Paths in a Binary Tree.java new file mode 100644 index 00000000..87acbbf4 --- /dev/null +++ b/Medium/Pseudo-Palindromic Paths in a Binary Tree.java @@ -0,0 +1,51 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public int pseudoPalindromicPaths (TreeNode root) { + int[] result = {0}; + Map map = new HashMap<>(); + helper(root, map, result); + return result[0]; + } + + private void helper(TreeNode root, Map map, int[] result) { + if (root == null) { + return; + } + map.put(root.val, map.getOrDefault(root.val, 0) + 1); + if (root.left == null && root.right == null) { + if (isPseudoPalindromic(map)) { + result[0]++; + } + } + helper(root.left, map, result); + helper(root.right, map, result); + map.put(root.val, map.getOrDefault(root.val, 0) - 1); + } + + private static boolean isPseudoPalindromic(Map map) { + boolean oddFound = false; + for (Integer key : map.keySet()) { + if (map.get(key) % 2 != 0) { + if (oddFound) { + return false; + } + oddFound = true; + } + } + return true; + } +} diff --git a/Medium/Push Dominoes.java b/Medium/Push Dominoes.java new file mode 100644 index 00000000..16753989 --- /dev/null +++ b/Medium/Push Dominoes.java @@ -0,0 +1,32 @@ +class Solution { + public String pushDominoes(String dominoes) { + int[] forces = new int[dominoes.length()]; + int force = 0; + for (int i = 0; i < dominoes.length(); i++) { + if (dominoes.charAt(i) == 'R') { + force = dominoes.length(); + } else if (dominoes.charAt(i) == 'L') { + force = 0; + } else { + force = Math.max(force - 1, 0); + } + forces[i] += force; + } + force = 0; + for (int i = dominoes.length() - 1; i >= 0; i--) { + if (dominoes.charAt(i) == 'L') { + force = dominoes.length(); + } else if (dominoes.charAt(i) == 'R') { + force = 0; + } else { + force = Math.max(force - 1, 0); + } + forces[i] -= force; + } + StringBuilder result = new StringBuilder(); + for (int i = 0; i < forces.length; i++) { + result.append(forces[i] > 0 ? 'R' : (forces[i] < 0 ? 'L' : '.')); + } + return result.toString(); + } +} diff --git a/Medium/Put Boxes Into the Warehouse I.java b/Medium/Put Boxes Into the Warehouse I.java new file mode 100644 index 00000000..3d8b4a59 --- /dev/null +++ b/Medium/Put Boxes Into the Warehouse I.java @@ -0,0 +1,15 @@ +class Solution { + public int maxBoxesInWarehouse(int[] boxes, int[] warehouse) { + Arrays.sort(boxes); + for (int i = 1; i < warehouse.length; i++) { + warehouse[i] = Math.min(warehouse[i - 1], warehouse[i]); + } + int count = 0; + for (int i = warehouse.length - 1; i >= 0; i--) { + if (count < boxes.length && boxes[count] <= warehouse[i]) { + count++; + } + } + return count; + } +} diff --git a/Medium/Queries on a Permutation With Key.java b/Medium/Queries on a Permutation With Key.java new file mode 100644 index 00000000..5738ab0c --- /dev/null +++ b/Medium/Queries on a Permutation With Key.java @@ -0,0 +1,16 @@ +class Solution { + public int[] processQueries(int[] queries, int m) { + LinkedList list = new LinkedList<>(); + for (int i = 1; i <= m; i++) { + list.add(i); + } + int[] result = new int[queries.length]; + for (int i = 0; i < queries.length; i++) { + int idx = list.indexOf(queries[i]); + result[i] = idx; + list.remove(idx); + list.addFirst(queries[i]); + } + return result; + } +} diff --git a/Medium/Queue Reconstruction By Height.java b/Medium/Queue Reconstruction By Height.java index 5314da67..4f422303 100644 --- a/Medium/Queue Reconstruction By Height.java +++ b/Medium/Queue Reconstruction By Height.java @@ -1,20 +1,11 @@ class Solution { public int[][] reconstructQueue(int[][] people) { - Arrays.sort(people, new Comparator(){ - public int compare(int[] o1, int[] o2) { - int c = o2[0] - o1[0]; - if (c != 0) { - return c; - } - return o1[1] - o2[1]; - } - }); - System.out.println(); - List list = new ArrayList<>(); + Arrays.sort(people, (o1, o2) -> o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0]); + List result = new ArrayList<>(); for (int[] p : people) { - list.add(p[1], p); + result.add(p[1], p); } int n = people.length; - return list.toArray(new int[n][2]); + return result.toArray(new int[n][2]); } } diff --git a/Medium/README.md b/Medium/README.md index 3907727e..cb496742 100644 --- a/Medium/README.md +++ b/Medium/README.md @@ -1,337 +1,795 @@ # Medium LeetCode-Java-Solutions S.no | Coding Problem --- | --- -1|[Range Sum Query 2D-Immutable](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Range%20Sum%20Query%202D-Immutable.java) -2|[Combination Sum III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Combination%20Sum%20III.java) -3|[Divide Two Integers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Divide%20Two%20Integers.java) -4|[Ugly Number II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Ugly%20Number%20II.java) -5|[Set Matrix Zeroes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Set%20Matrix%20Zeroes.java) -6|[Container With Most Water](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Container%20With%20Most%20Water.java) -7|[Spiral Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Spiral%20Matrix.java) -8|[Rabbits in Forest](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rabbits%20in%20Forest.java) -9|[Binary Tree Vertical Order Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Vertical%20Order%20Traversal.java) -10|[Basic Calculator II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Basic%20Calculator%20II.java) -11|[Corporate Flight Bookings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Corporate%20Flight%20Bookings.java) -12|[Custom Sort String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Custom%20Sort%20String.java) -13|[Minimum Moves to Equal Array Elements II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Moves%20to%20Equal%20Array%20Elements%20II.java) -14|[Rotate List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rotate%20List.java) -15|[Flatten Nested List Iterator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Flatten%20Nested%20List%20Iterator.java) -16|[Minimum Number of Arrows to Burst Balloons](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Number%20of%20Arrows%20to%20Burst%20Balloons.java) -17|[Count Complete Tree Nodes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Complete%20Tree%20Nodes.java) -18|[Search in Rotated Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Search%20in%20Rotated%20Sorted%20Array.java) -19|[Subarray Product Less Than K](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Subarray%20Product%20Less%20Than%20K.java) -20|[Unique Binary Search Trees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Unique%20Binary%20Search%20Trees.java) -21|[Shuffle an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Shuffle%20an%20Array.java) -22|[Permutation in String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Permutation%20in%20String.java) -23|[Flatten a Multilevel Doubly Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Flatten%20a%20Multilevel%20Doubly%20Linked%20List.java) -24|[Search in Rotated Sorted Array II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Search%20in%20Rotated%20Sorted%20Array%20II.java) -25|[Pour Water](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Pour%20Water.java) -26|[Find Leaves of Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Leaves%20of%20Binary%20Tree.java) -27|[Majority Element II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Majority%20Element%20II.java) -28|[Course Schedule II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Course%20Schedule%20II.java) -29|[Design Circular Queue](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Circular%20Queue.java) -30|[Battleships in a board](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Battleships%20in%20a%20board.java) -31|[Next Greater Element III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Next%20Greater%20Element%20III.java) -32|[Linked List Components](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Linked%20List%20Components.java) -33|[Multiply Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Multiply%20Strings.java) -34|[Convert Binary Search Tree to Sorted Doubly Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Convert%20Binary%20Search%20Tree%20to%20Sorted%20Doubly%20Linked%20List.java) -35|[Add One Row to Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Add%20One%20Row%20to%20Tree.java) -36|[Binary Tree Pruning](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Pruning.java) -37|[Word Break](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Word%20Break.java) -38|[Interval List Intersections](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Interval%20List%20Intersections.java) -39|[Pow](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Pow.java) -40|[Daily Temperatures](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Daily%20Temperatures.java) -41|[Implement Rand10() Using Rand7()](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Implement%20Rand10()%20Using%20Rand7().java) -42|[Palindromic Substrings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Palindromic%20Substrings.java) -43|[Reverse Substrings Between Each Pair of Parentheses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reverse%20Substrings%20Between%20Each%20Pair%20of%20Parentheses.java) -44|[Design File System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20File%20System.java) -45|[Lowest Common Ancestor of Deepest Leaves](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Lowest%20Common%20Ancestor%20of%20Deepest%20Leaves.java) -46|[Grumpy Bookstore Owner](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Grumpy%20Bookstore%20Owner.java) -47|[Remove Duplicates From Sorted Array II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Duplicates%20From%20Sorted%20Array%20II.java) -48|[Validate IP Address](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Validate%20IP%20Address.java) -49|[Boats to Save People](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Boats%20to%20Save%20People.java) -50|[Ternary Expression Parser](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Ternary%20Expression%20Parser.java) -51|[Find Peak Element](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Peak%20Element.java) -52|[Design Tic-Tac-Toe](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Tic-Tac-Toe.java) -53|[Keys and Rooms](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Keys%20and%20Rooms.java) -54|[Counting Bits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Counting%20Bits.java) -55|[Split Linked List into Parts](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Split%20Linked%20List%20into%20Parts.java) -56|[Number of Connected Components in an Undirected Graph](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Connected%20Components%20in%20an%20Undirected%20Graph.java) -57|[Task Scheduler](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Task%20Scheduler.java) -58|[Online Election](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Online%20Election.java) -59|[Maximum Width Ramp](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Width%20Ramp.java) -60|[Time Based Key-Value Store](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Time%20Based%20Key-Value%20Store.java) -61|[Sum Root to Leaf Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sum%20Root%20to%20Leaf%20Numbers.java) -62|[Kth Largest Element in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Kth%20Largest%20Element%20in%20an%20Array.java) -63|[Bitwise AND of Numbers Range](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Bitwise%20AND%20of%20Numbers%20Range.java) -64|[Binary Tree Longest Consecutive Sequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Longest%20Consecutive%20Sequence.java) -65|[Largest BST Subtree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Largest%20BST%20Subtree.java) -66|[Populating Next Right Pointers in Each Node II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Populating%20Next%20Right%20Pointers%20in%20Each%20Node%20II.java) -67|[Online Stock Span](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Online%20Stock%20Span.java) -68|[Combination Sum II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Combination%20Sum%20II.java) -69|[Insert Into a Cyclic Sorted List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Insert%20Into%20a%20Cyclic%20Sorted%20List.java) -70|[Reconstruct Itinerary](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reconstruct%20Itinerary.java) -71|[Partition Labels](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Partition%20Labels.java) -72|[Distribute Coins in Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Distribute%20Coins%20in%20Binary%20Tree.java) -73|[Longest Palindromic Substring](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Palindromic%20Substring.java) -74|[Simplify Path](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Simplify%20Path.java) -75|[Zigzag Iterator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Zigzag%20Iterator.java) -76|[Max Chunks To Make Sorted](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Max%20Chunks%20To%20Make%20Sorted.java) -77|[Is Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Is%20Subsequence.java) -78|[Reverse Linked List II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reverse%20Linked%20List%20II.java) -79|[Complex Number Multiplication](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Complex%20Number%20Multiplication.java) -80|[Maximum Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Binary%20Tree.java) -81|[Meeting Rooms II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Meeting%20Rooms%20II.java) -82|[Fraction to Recurring Decimal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Fraction%20to%20Recurring%20Decimal.java) -83|[Add and Search Word - Data structure design](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Add%20and%20Search%20Word%20-%20Data%20structure%20design.java) -84|[Super Ugly Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Super%20Ugly%20Number.java) -85|[Escape The Ghosts](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Escape%20The%20Ghosts.java) -86|[Max Increase to Keep City Skyline](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Max%20Increase%20to%20Keep%20City%20Skyline.java) -87|[Minimum Path Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Path%20Sum.java) -88|[Valid Tic-Tac-Toe State](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Valid%20Tic-Tac-Toe%20State.java) -89|[Shortest Completing Word](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Shortest%20Completing%20Word.java) -90|[01 Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/01%20Matrix.java) -91|[As Far from Land as Possible](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/As%20Far%20from%20Land%20as%20Possible.java) -92|[Number of Matching Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Matching%20Subsequence.java) -93|[Car Pooling](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Car%20Pooling.java) -94|[Generate Parentheses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Generate%20Parentheses.java) -95|[Exclusive Time of Functions](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Exclusive%20Time%20of%20Functions.java) -96|[Sort Characters By Frequency](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20Characters%20By%20Frequency.java) -97|[Max Consecutives Ones II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Max%20Consecutives%20Ones%20II.java) -98|[Number of Islands](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Islands.java) -99|[Reverse Words in a String II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reverse%20Words%20in%20a%20String%20II.java) -100|[Binary Tree Upside Down](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Upside%20Down.java) -101|[Count Univalue Subtrees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Univalue%20Subtrees.java) -102|[Split BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Split%20BST.java) -103|[All Possible Full Binary Trees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/All%20Possible%20Full%20Binary%20Trees.java) -104|[Convert Sorted List to Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Convert%20Sorted%20List%20to%20Binary%20Search%20Tree.java) -105|[Word Search](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Word%20Search.java) -106|[Add Two Numbers II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Add%20Two%20Numbers%20II.java) -107|[Sort List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20List.java) -108|[Gray Code](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Gray%20Code.java) -109|[Rotate Function](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rotate%20Function.java) -110|[Bulb Switcher](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Bulb%20Switcher.java) -111|[Implement Trie (Prefix Tree)](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Implement%20Trie%20(Prefix%20Tree).java) -112|[Contains Duplicate III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Contains%20Duplicate%20III.java) -113|[Copy List with Random Pointer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Copy%20List%20with%20Random%20Pointer.java) -114|[Design Hit Counter](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Hit%20Counter.java) -115|[Medium](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Medium.md) -116|[Binary Tree Inorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Inorder%20Traversal.java) -117|[Maximum Product Subarray](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Product%20Subarray.java) -118|[Prison Cells After N Days](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Prison%20Cells%20After%20N%20Days.java) -119|[Evaluate Reverse Polish Notation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Evaluate%20Reverse%20Polish%20Notation.java) -120|[H-Index](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/H-Index.java) -121|[Mini Parser](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Mini%20Parser.java) -122|[Line Reflection](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Line%20Reflection.java) -123|[Linked List Cycle II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Linked%20List%20Cycle%20II.java) -124|[Minimum Size Subarray Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Size%20Subarray%20Sum.java) -125|[Next Greater Element II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Next%20Greater%20Element%20II.java) -126|[Decode String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Decode%20String.java) -127|[Unique Paths II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Unique%20Paths%20II.java) -128|[Shifting Letters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Shifting%20Letters.java) -129|[Subarray Sum Equals K](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Subarray%20Sum%20Equals%20K.java) -130|[Graph Valid Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Graph%20Valid%20Tree.java) -131|[Flatten Binary Tree to Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Flatten%20Binary%20Tree%20to%20Linked%20List.java) -132|[Top K Frequent Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Top%20K%20Frequent%20Elements.java) -133|[Find First and Last Position of Element in Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20First%20and%20Last%20Position%20of%20Element%20in%20Sorted%20Array.java) -134|[Broken Calculator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Broken%20Calculator.java) -135|[Design Twitter](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Twitter.java) -136|[Nested List Weight Sum II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Nested%20List%20Weight%20Sum%20II.java) -137|[Permutations II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Permutations%20II.java) -138|[Sort An Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20An%20Array.java) -139|[Construct Quad Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Construct%20Quad%20Tree.java) -140|[Game of Life](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Game%20of%20Life.java) -141|[Remove Nth Node From End of List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Nth%20Node%20From%20End%20of%20List.java) -142|[Random Pick Index](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Random%20Pick%20Index.java) -143|[My Calendar II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/My%20Calendar%20II.java) -144|[Search for a range](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Search%20for%20a%20range.java) -145|[Binary Tree Right Side View](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Right%20Side%20View.java) -146|[Longest Substring Without Repeating Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Substring%20Without%20Repeating%20Characters.java) -147|[Single Number III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Single%20Number%20III.java) -148|[Candy Crush](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Candy%20Crush.java) -149|[Web Crawler](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Web%20Crawler.java) -150|[Lonely Pixel I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Lonely%20Pixel%20I.java) -151|[Reorganize String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reorganize%20String.java) -152|[Insertion Sort List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Insertion%20Sort%20List.java) -153|[Peeking Iterator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Peeking%20Iterator.java) -154|[Reorder List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reorder%20List.java) -155|[Unique Paths](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Unique%20Paths.java) -156|[Reconstruct Original Digits from English](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reconstruct%20Original%20Digits%20from%20English.java) -157|[Walls and Gates](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Walls%20and%20Gates.java) -158|[Total Hamming Distance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Total%20Hamming%20Distance.java) -159|[Rectangle Area](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rectangle%20Area.java) -160|[Binary Search Tree to Greater Sum Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Search%20Tree%20to%20Greater%20Sum%20Tree.java) -161|[Longest Absolute File Path](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Absolute%20File%20Path.java) -162|[Single Element in a Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Single%20Element%20in%20a%20Sorted%20Array.java) -163|[Binary Search Tree Iterator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Search%20Tree%20Iterator.java) -164|[Find K Closest Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20K%20Closest%20Elements.java) -165|[Rotate Image](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rotate%20Image.java) -166|[Next Permutation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Next%20Permutation.java) -167|[Design Phone Directory](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Phone%20Directory.java) -168|[Jump Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Jump%20Game.java) -169|[H-Index II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/H-Index%20II.java) -170|[Subarray Sums Divisible by K](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Subarray%20Sums%20Divisible%20by%20K.java) -171|[Kill Process](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Kill%20Process.java) -172|[Boundary of Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Boundary%20of%20Binary%20Tree.java) -173|[Course Schedule](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Course%20Schedule.java) -174|[Insert Delete GetRandom O(1)](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Insert%20Delete%20GetRandom%20O(1).java) -175|[Coin Change 2](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Coin%20Change%202.java) -176|[Find Duplicate Subtrees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Duplicate%20Subtrees.java) -177|[Letter Tiles Possibilities](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Letter%20Tiles%20Possibilities.java) -178|[Palindrome Partitioning](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Palindrome%20Partitioning.java) -179|[Longest Palindromic Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Palindromic%20Subsequence.java) -180|[Expressive Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Expressive%20Words.java) -181|[Linked List Random Node](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Linked%20List%20Random%20Node.java) -182|[Find Minimum in Rotated Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Minimum%20in%20Rotated%20Sorted%20Array.java) -183|[3Sum Closest](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/3Sum%20Closest.java) -184|[Permutations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Permutations.java) -185|[Next Greater Node In Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Next%20Greater%20Node%20In%20Linked%20List.java) -186|[Map Sum Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Map%20Sum%20Pairs.java) -187|[Minimum Genetic Mutation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Genetic%20Mutation.java) -188|[Maximum Binary Tree II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Binary%20Tree%20II.java) -189|[Delete Operation for Two Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Delete%20Operation%20for%20Two%20Strings.java) -190|[Inorder Successor in BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Inorder%20Successor%20in%20BST.java) -191|[Array Nesting](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Array%20Nesting.java) -192|[Output Contest Matches](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Output%20Contest%20Matches.java) -193|[Serialize and Deserialize BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Serialize%20and%20Deserialize%20BST.java) -194|[Find the duplicate number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20duplicate%20number.java) -195|[Single Number II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Single%20Number%20II.java) -196|[Statistics from a Large Sample](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Statistics%20from%20a%20Large%20Sample.java) -197|[Accounts Merge](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Accounts%20Merge.java) -198|[Reverse Words in a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reverse%20Words%20in%20a%20String.java) -199|[Find Duplicate File in System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Duplicate%20File%20in%20System.java) -200|[Delete Node in a BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Delete%20Node%20in%20a%20BST.java) -201|[Is Graph Bipartite](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Is%20Graph%20Bipartite.java) -202|[Minesweeper](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minesweeper.java) -203|[Remove K Digits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20K%20Digits.java) -204|[Next Closest Time](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Next%20Closest%20Time.java) -205|[Self Dividing Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Self%20Dividing%20Numbers.java) -206|[Replace Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Replace%20Words.java) -207|[Longest Increasing Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Increasing%20Subsequence.java) -208|[Find Right Interval](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Right%20Interval.java) -209|[Non Overlapping Intervals](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Non%20Overlapping%20Intervals.java) -210|[Range Addition](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Range%20Addition.java) -211|[3Sum Smaller](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/3Sum%20Smaller.java) -212|[Shortest Way to Form String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Shortest%20Way%20to%20Form%20String.java) -213|[Missing Element in Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Missing%20Element%20in%20Sorted%20Array.java) -214|[Insufficient Nodes in Root to Leaf Paths](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Insufficient%20Nodes%20in%20Root%20to%20Leaf%20Paths.java) -215|[Maximum Width of Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Width%20of%20Binary%20Tree.java) -216|[Product of Array Except self](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Product%20of%20Array%20Except%20self.java) -217|[Sort Colors](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20Colors.java) -218|[Arithmetic Slices](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Arithmetic%20Slices.java) -219|[Number of Dice Rolls With Target Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Dice%20Rolls%20With%20Target%20Sum.java) -220|[Perfect Squares](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Perfect%20Squares.java) -221|[Search a 2D Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Search%20a%202D%20Matrix.java) -222|[Satisfisbility of Equality Equations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Satisfisbility%20of%20Equality%20Equations.java) -223|[Maximum Length of Pair Chain](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Length%20of%20Pair%20Chain.java) -224|[Queue Reconstruction By Height](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Queue%20Reconstruction%20By%20Height.java) -225|[Bulls and Cows](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Bulls%20and%20Cows.java) -226|[Unique Word Abbrevation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Unique%20Word%20Abbrevation.java) -227|[Range Sum Query - Mutable](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Range%20Sum%20Query%20-%20Mutable.java) -228|[Delete Nodes And Return Forest](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Delete%20Nodes%20And%20Return%20Forest.java) -229|[4Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/4Sum.java) -230|[Missing Ranges](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Missing%20Ranges.java) -231|[Sentence Similarity II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sentence%20Similarity%20II.java) -232|[Evaluate Division](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Evaluate%20Division.java) -233|[Find K Pairs with Smallest Sums](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20K%20Pairs%20with%20Smallest%20Sums.java) -234|[Partition List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Partition%20List.java) -235|[Encode and Decode Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Encode%20and%20Decode%20Strings.java) -236|[Decrease Elements To Make Array Zigzag](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Decrease%20Elements%20To%20Make%20Array%20Zigzag.java) -237|[Maximum Level Sum of a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Level%20Sum%20of%20a%20Binary%20Tree.java) -238|[All Nodes Distance K in Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/All%20Nodes%20Distance%20K%20in%20Binary%20Tree.java) -239|[Design Circular Deque](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Circular%20Deque.java) -240|[Design Log Storage System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Log%20Storage%20System.java) -241|[Decode Ways](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Decode%20Ways.java) -242|[Sort Transformed Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20Transformed%20Array.java) -243|[Wiggle Sort](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Wiggle%20Sort.java) -244|[Path Sum II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Path%20Sum%20II.java) -245|[Subsets](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Subsets.java) -246|[Increasing Subsequences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Increasing%20Subsequences.java) -247|[Number of Distinct Islands](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Distinct%20Islands.java) -248|[Add Two Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Add%20Two%20Numbers.java) -249|[Fruit Into Baskets](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Fruit%20Into%20Baskets.java) -250|[Lowest Common Ancestor of a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Lowest%20Common%20Ancestor%20of%20a%20Binary%20Tree.java) -251|[Complete Binary Tree Insertor](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Complete%20Binary%20Tree%20Insertor.java) -252|[Clone Graph](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Clone%20Graph.java) -253|[Binary Tree Preorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Preorder%20Traversal.java) -254|[Random Pick With Weight](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Random%20Pick%20With%20Weight.java) -255|[Vertical Order Traversal Of Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Vertical%20Order%20Traversal%20Of%20Binary%20Tree.java) -256|[Remove Duplicates from Sorted List II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Duplicates%20from%20Sorted%20List%20II.java) -257|[Search in a Sorted Array of Unknown Size](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Search%20in%20a%20Sorted%20Array%20of%20Unknown%20Size.java) -258|[Rectangle Overlap](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rectangle%20Overlap.java) -259|[Analyze User Website Visit Pattern](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Analyze%20User%20Website%20Visit%20Pattern.java) -260|[Combination Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Combination%20Sum.java) -261|[Solve the Equation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Solve%20the%20Equation.java) -262|[The Earliest Moment When Everyone Become Friends](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/The%20Earliest%20Moment%20When%20Everyone%20Become%20Friends.java) -263|[Verify Preorder Serialization of a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Verify%20Preorder%20Serialization%20of%20a%20Binary%20Tree.java) -264|[Optimal Division](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Optimal%20Division.java) -265|[Score of Parentheses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Score%20of%20Parentheses.java) -266|[Merge Intervals](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Merge%20Intervals.java) -267|[Kth Smallest Element in a BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Kth%20Smallest%20Element%20in%20a%20BST.java) -268|[Coin Change](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Coin%20Change.java) -269|[Find the Celebrity](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20Celebrity.java) -270|[Array Circular Loop](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Array%20Circular%20Loop.java) -271|[Snapshot Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Snapshot%20Array.java) -272|[Top K Frequent Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Top%20K%20Frequent%20Words.java) -273|[Asteroid Collision](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Asteroid%20Collision.java) -274|[Encode and Decode TinyURL](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Encode%20and%20Decode%20TinyURL.java) -275|[Insert into a Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Insert%20into%20a%20Binary%20Search%20Tree.java) -276|[Word Ladder](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Word%20Ladder.java) -277|[Inorder Successor in BST II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Inorder%20Successor%20in%20BST%20II.java) -278|[Find and Replace Pattern](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20and%20Replace%20Pattern.java) -279|[Number of Longest Increasing Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Longest%20Increasing%20Subsequence.java) -280|[Remove Comments](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Comments.java) -281|[Pancake Sorting](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Pancake%20Sorting.java) -282|[Maximum Size Subarray Sum Equals k](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Size%20Subarray%20Sum%20Equals%20k.java) -283|[3Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/3Sum.java) -284|[Valid Triangle Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Valid%20Triangle%20Number.java) -285|[Kth Smallest Element in a Sorted Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Kth%20Smallest%20Element%20in%20a%20Sorted%20Matrix.java) -286|[String to Integer(atoi)](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/String%20to%20Integer(atoi).java) -287|[All Paths From Source to Target](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/All%20Paths%20From%20Source%20to%20Target.java) -288|[Binary Tree Longest Consecutive Sequence II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Longest%20Consecutive%20Sequence%20II.java) -289|[Friend Circles](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Friend%20Circles.java) -290|[Swap Nodes in Pair](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Swap%20Nodes%20in%20Pair.java) -291|[Plus One Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Plus%20One%20Linked%20List.java) -292|[Teemo Attacking](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Teemo%20Attacking.java) -293|[Compare Version Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Compare%20Version%20Numbers.java) -294|[Smallest String Starting From Leaf](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Smallest%20String%20Starting%20From%20Leaf.java) -295|[Count Numbers With Unique Digits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Numbers%20With%20Unique%20Digits.java) -296|[Uncrossed Lines](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Uncrossed%20Lines.java) -297|[Vowel Spellchecker](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Vowel%20Spellchecker.java) -298|[Contiguous Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Contiguous%20Array.java) -299|[Longest Well-Performing Interval](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Well-Performing%20Interval.java) -300|[Find Bottom Left Tree Value](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Bottom%20Left%20Tree%20Value.java) -301|[Score After Flipping Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Score%20After%20Flipping%20Matrix.java) -302|[4 Sum II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/4%20Sum%20II.java) -303|[Most Frequent Subtree Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Most%20Frequent%20Subtree%20Sum.java) -304|[Combinations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Combinations.java) -305|[RLE Iterator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/RLE%20Iterator.java) -306|[Spiral Matrix II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Spiral%20Matrix%20II.java) -307|[Find Largest Value in Tree Row](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Largest%20Value%20in%20Tree%20Row.java) -308|[Minimum Time Difference](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Time%20Difference.java) -309|[Find all Duplicates in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20all%20Duplicates%20in%20an%20Array.java) -310|[Diagonal Traverse](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Diagonal%20Traverse.java) -311|[Print Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Print%20Binary%20Tree.java) -312|[Masking Personal Information](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Masking%20Personal%20Information.java) -313|[Summary Ranges](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Summary%20Ranges.java) -314|[Letter Combinations of a Phone Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Letter%20Combinations%20of%20a%20Phone%20Number.java) -315|[Odd Even Linked Lists](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Odd%20Even%20Linked%20Lists.java) -316|[Find K-Length Substrings With No Repeated Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20K-Length%20Substrings%20With%20No%20Repeated%20Characters.java) -317|[ZigZag Conversion](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/ZigZag%20Conversion.java) -318|[Water & Jug Problem](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Water%20&%20Jug%20Problem.java) -319|[Find and Replace in String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20and%20Replace%20in%20String.java) -320|[Construct Binary Tree from Inorder and Postorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Construct%20Binary%20Tree%20from%20Inorder%20and%20Postorder%20Traversal.java) -321|[Flatten 2D Vector](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Flatten%202D%20Vector.java) -322|[Hand of Straights](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Hand%20of%20Straights.java) -323|[Maximum Average Subtree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Average%20Subtree.java) -324|[Repeated DNA Sequences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Repeated%20DNA%20Sequences.java) -325|[Integer To Roman](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Integer%20To%20Roman.java) -326|[My Calendar I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/My%20Calendar%20I.java) -327|[Longest Line of Consecutive One in Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Line%20of%20Consecutive%20One%20in%20Matrix.java) -328|[Group Shifted Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Group%20Shifted%20Strings.java) -329|[Reverse Nodes in k-group](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reverse%20Nodes%20in%20k-group.java) -330|[One Edit Distance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/One%20Edit%20Distance.java) -331|[Add Bold Tag in String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Add%20Bold%20Tag%20in%20String.java) -332|[Open The Lock](https://github.com/varunu28/LeetCode-Java-Solutions/blob/master/Medium/Open%20The%20Lock.java) -333|[Target Sum](https://github.com/varunu28/LeetCode-Java-Solutions/blob/master/Medium/Target%20Sum.java) - +1|[Jump Game II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Jump%20Game%20II.java) +2|[Unique Paths II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Unique%20Paths%20II.java) +3|[Search a 2D Matrix II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Search%20a%202D%20Matrix%20II.java) +4|[First Unique Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/First%20Unique%20Number.java) +5|[Minimum Number of Vertices to Reach All Nodes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Number%20of%20Vertices%20to%20Reach%20All%20Nodes.java) +6|[Inorder Successor in BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Inorder%20Successor%20in%20BST.java) +7|[3Sum Closest](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/3Sum%20Closest.java) +8|[Binary Tree Zigzag Level Order Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Zigzag%20Level%20Order%20Traversal.java) +9|[Successful Pairs of Spells and Potions](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Successful%20Pairs%20of%20Spells%20and%20Potions.java) +10|[Sort the Jumbled Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20the%20Jumbled%20Numbers.java) +11|[Closest Nodes Queries in a Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Closest%20Nodes%20Queries%20in%20a%20Binary%20Search%20Tree.java) +12|[House Robber III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/House%20Robber%20III.java) +13|[Out of Boundary Paths](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Out%20of%20Boundary%20Paths.java) +14|[Campus Bikes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Campus%20Bikes.java) +15|[Arithmetic Subarrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Arithmetic%20Subarrays.java) +16|[Binary Tree Level Order Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Level%20Order%20Traversal.java) +17|[Vowels of All Substrings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Vowels%20of%20All%20Substrings.java) +18|[Grumpy Bookstore Owner](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Grumpy%20Bookstore%20Owner.java) +19|[Minimize the Maximum Difference of Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimize%20the%20Maximum%20Difference%20of%20Pairs.java) +20|[Linked List Cycle II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Linked%20List%20Cycle%20II.java) +21|[Dota2 Senate](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Dota2%20Senate.java) +22|[Largest Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Largest%20Number.java) +23|[Stone Game II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Stone%20Game%20II.java) +24|[Web Crawler](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Web%20Crawler.java) +25|[Champagne Tower](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Champagne%20Tower.java) +26|[Candy Crush](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Candy%20Crush.java) +27|[Bold Words in String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Bold%20Words%20in%20String.java) +28|[Diagonal Traverse](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Diagonal%20Traverse.java) +29|[Shortest Way to Form String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Shortest%20Way%20to%20Form%20String.java) +30|[Maximum Number of Coins You Can Get](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Number%20of%20Coins%20You%20Can%20Get.java) +31|[Masking Personal Information](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Masking%20Personal%20Information.java) +32|[The Earliest Moment When Everyone Become Friends](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/The%20Earliest%20Moment%20When%20Everyone%20Become%20Friends.java) +33|[Divide Two Integers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Divide%20Two%20Integers.java) +34|[Minimum Cost to Connect Sticks](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Cost%20to%20Connect%20Sticks.java) +35|[Lowest Common Ancestor of Deepest Leaves](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Lowest%20Common%20Ancestor%20of%20Deepest%20Leaves.java) +36|[Single Number III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Single%20Number%20III.java) +37|[Next Greater Element III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Next%20Greater%20Element%20III.java) +38|[Making File Names Unique](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Making%20File%20Names%20Unique.java) +39|[Validate Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Validate%20Binary%20Search%20Tree.java) +40|[Sparse Matrix Multiplication](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sparse%20Matrix%20Multiplication.java) +41|[Uncrossed Lines](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Uncrossed%20Lines.java) +42|[Capacity To Ship Packages Within D Days](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Capacity%20To%20Ship%20Packages%20Within%20D%20Days.java) +43|[Count Vowel Strings in Ranges](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Vowel%20Strings%20in%20Ranges.java) +44|[Set Matrix Zeroes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Set%20Matrix%20Zeroes.java) +45|[Flatten a Multilevel Doubly Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Flatten%20a%20Multilevel%20Doubly%20Linked%20List.java) +46|[Word Subsets](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Word%20Subsets.java) +47|[Find Smallest Common Element in All Rows](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Smallest%20Common%20Element%20in%20All%20Rows.java) +48|[Reverse Integer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reverse%20Integer.java) +49|[Most Popular Video Creator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Most%20Popular%20Video%20Creator.java) +50|[Most Stones Removed with Same Row or Column](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Most%20Stones%20Removed%20with%20Same%20Row%20or%20Column.java) +51|[Shortest Word Distance II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Shortest%20Word%20Distance%20II.java) +52|[Total Hamming Distance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Total%20Hamming%20Distance.java) +53|[Sort Linked List Already Sorted Using Absolute Values](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20Linked%20List%20Already%20Sorted%20Using%20Absolute%20Values.java) +54|[Count Number of Homogenous Substrings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Number%20of%20Homogenous%20Substrings.java) +55|[Score of Parentheses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Score%20of%20Parentheses.java) +56|[Gas Station](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Gas%20Station.java) +57|[Number of Subarrays with Bounded Maximum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Subarrays%20with%20Bounded%20Maximum.java) +58|[Kth Largest Sum in a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Kth%20Largest%20Sum%20in%20a%20Binary%20Tree.java) +59|[Smallest Number in Infinite Set](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Smallest%20Number%20in%20Infinite%20Set.java) +60|[All Divisions With the Highest Score of a Binary Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/All%20Divisions%20With%20the%20Highest%20Score%20of%20a%20Binary%20Array.java) +61|[Non-decreasing Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Non-decreasing%20Array.java) +62|[Palindrome Partitioning](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Palindrome%20Partitioning.java) +63|[Find all Duplicates in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20all%20Duplicates%20in%20an%20Array.java) +64|[Find Largest Value in Each Tree Row](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Largest%20Value%20in%20Each%20Tree%20Row.java) +65|[Flatten 2D Vector](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Flatten%202D%20Vector.java) +66|[Find All Lonely Numbers in the Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20All%20Lonely%20Numbers%20in%20the%20Array.java) +67|[Furthest Building You Can Reach](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Furthest%20Building%20You%20Can%20Reach.java) +68|[Convert Binary Search Tree to Sorted Doubly Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Convert%20Binary%20Search%20Tree%20to%20Sorted%20Doubly%20Linked%20List.java) +69|[Design a File Sharing System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20a%20File%20Sharing%20System.java) +70|[Watering Plants](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Watering%20Plants.java) +71|[Smallest String Starting From Leaf](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Smallest%20String%20Starting%20From%20Leaf.java) +72|[Throne Inheritence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Throne%20Inheritence.java) +73|[Minimum Remove to Make Valid Parentheses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Remove%20to%20Make%20Valid%20Parentheses.java) +74|[Implement Trie II (Prefix Tree)](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Implement%20Trie%20II%20(Prefix%20Tree).java) +75|[Remove Covered Intervals](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Covered%20Intervals.java) +76|[Minimum Add to Make Parentheses Valid](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Add%20to%20Make%20Parentheses%20Valid.java) +77|[Arithmetic Slices](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Arithmetic%20Slices.java) +78|[Binary Tree Preorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Preorder%20Traversal.java) +79|[Time Needed to Inform All Employees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Time%20Needed%20to%20Inform%20All%20Employees.java) +80|[Kill Process](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Kill%20Process.java) +81|[Maximum Twin Sum of a Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Twin%20Sum%20of%20a%20Linked%20List.java) +82|[Line Reflection](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Line%20Reflection.java) +83|[Maximum Number of Occurrences of a Substring](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Number%20of%20Occurrences%20of%20a%20Substring.java) +84|[Frequency Tracker](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Frequency%20Tracker.java) +85|[Diameter of N-ary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Diameter%20of%20N-ary%20Tree.java) +86|[Maximum Number of Non-Overlapping Subarrays With Sum Equals Target](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Number%20of%20Non-Overlapping%20Subarrays%20With%20Sum%20Equals%20Target.java) +87|[Majority Element II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Majority%20Element%20II.java) +88|[Number of Ways to Split Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Ways%20to%20Split%20Array.java) +89|[Plus One Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Plus%20One%20Linked%20List.java) +90|[Append Characters to String to Make Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Append%20Characters%20to%20String%20to%20Make%20Subsequence.java) +91|[Longest Consecutive Sequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Consecutive%20Sequence.java) +92|[Find Minimum in Rotated Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Minimum%20in%20Rotated%20Sorted%20Array.java) +93|[Decrease Elements To Make Array Zigzag](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Decrease%20Elements%20To%20Make%20Array%20Zigzag.java) +94|[Binary Tree Longest Consecutive Sequence II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Longest%20Consecutive%20Sequence%20II.java) +95|[Concatenation of Consecutive Binary Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Concatenation%20of%20Consecutive%20Binary%20Numbers.java) +96|[Bitwise AND of Numbers Range](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Bitwise%20AND%20of%20Numbers%20Range.java) +97|[Maximum Points You Can Obtain from Cards](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Points%20You%20Can%20Obtain%20from%20Cards.java) +98|[Count Number of Teams](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Number%20of%20Teams.java) +99|[Sum of Subarray Minimums](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sum%20of%20Subarray%20Minimums.java) +100|[Binary Trees With Factors](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Trees%20With%20Factors.java) +101|[Prime Palindrome](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Prime%20Palindrome.java) +102|[Minimum Path Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Path%20Sum.java) +103|[Friend Circles](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Friend%20Circles.java) +104|[Matchsticks to Square](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Matchsticks%20to%20Square.java) +105|[Valid Sudoku](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Valid%20Sudoku.java) +106|[Four Divisors](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Four%20Divisors.java) +107|[As Far from Land as Possible](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/As%20Far%20from%20Land%20as%20Possible.java) +108|[Count Square Submatrices with All Ones](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Square%20Submatrices%20with%20All%20Ones.java) +109|[Linked List in Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Linked%20List%20in%20Binary%20Tree.java) +110|[Number of Nodes in the Sub-Tree With the Same Label](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Nodes%20in%20the%20Sub-Tree%20With%20the%20Same%20Label.java) +111|[Pseudo-Palindromic Paths in a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Pseudo-Palindromic%20Paths%20in%20a%20Binary%20Tree.java) +112|[Pancake Sorting](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Pancake%20Sorting.java) +113|[Walls and Gates](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Walls%20and%20Gates.java) +114|[Decode String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Decode%20String.java) +115|[Combination Sum II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Combination%20Sum%20II.java) +116|[Complete Binary Tree Insertor](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Complete%20Binary%20Tree%20Insertor.java) +117|[Minimum Moves to Equal Array Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Moves%20to%20Equal%20Array%20Elements.java) +118|[Design an ATM Machine](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20an%20ATM%20Machine.java) +119|[Split Linked List in Parts](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Split%20Linked%20List%20in%20Parts.java) +120|[Longest Word With All Prefixes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Word%20With%20All%20Prefixes.java) +121|[Binary Tree Pruning](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Pruning.java) +122|[Escape The Ghosts](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Escape%20The%20Ghosts.java) +123|[Longest Arithmetic Sequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Arithmetic%20Sequence.java) +124|[Longest Arithmetic Subsequence of Given Difference](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Arithmetic%20Subsequence%20of%20Given%20Difference.java) +125|[Equal Row and Column Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Equal%20Row%20and%20Column%20Pairs.java) +126|[Count Numbers With Unique Digits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Numbers%20With%20Unique%20Digits.java) +127|[Maximum Average Subtree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Average%20Subtree.java) +128|[Product of Array Except self](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Product%20of%20Array%20Except%20self.java) +129|[Find Bottom Left Tree Value](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Bottom%20Left%20Tree%20Value.java) +130|[Shifting Letters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Shifting%20Letters.java) +131|[Maximum Product of Splitted Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Product%20of%20Splitted%20Binary%20Tree.java) +132|[Minimum Knight Moves](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Knight%20Moves.java) +133|[3Sum With Multiplicity](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/3Sum%20With%20Multiplicity.java) +134|[Rotting Oranges](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rotting%20Oranges.java) +135|[Palindromic Substrings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Palindromic%20Substrings.java) +136|[Maximum of Absolute Value Expression](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20of%20Absolute%20Value%20Expression.java) +137|[Insert Interval](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Insert%20Interval.java) +138|[Is Graph Bipartite](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Is%20Graph%20Bipartite.java) +139|[Add Two Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Add%20Two%20Numbers.java) +140|[Find Permutation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Permutation.java) +141|[Number of Burgers with No Waste of Ingredients](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Burgers%20with%20No%20Waste%20of%20Ingredients.java) +142|[Finding the Users Active Minutes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Finding%20the%20Users%20Active%20Minutes.java) +143|[Validate Stack Sequences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Validate%20Stack%20Sequences.java) +144|[Number of Substrings Containing All Three Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Substrings%20Containing%20All%20Three%20Characters.java) +145|[Next Greater Element II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Next%20Greater%20Element%20II.java) +146|[Count and Say](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20and%20Say.java) +147|[Design Add and Search Words Data Structure](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Add%20and%20Search%20Words%20Data%20Structure.java) +148|[Maximum Score From Removing Stones](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Score%20From%20Removing%20Stones.java) +149|[Minimum Consecutive Cards to Pick Up](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Consecutive%20Cards%20to%20Pick%20Up.java) +150|[Score After Flipping Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Score%20After%20Flipping%20Matrix.java) +151|[Jump Game VI](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Jump%20Game%20VI.java) +152|[Design Browser History](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Browser%20History.java) +153|[Cheapest Flights Within K Stops](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Cheapest%20Flights%20Within%20K%20Stops.java) +154|[Meeting Scheduler](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Meeting%20Scheduler.java) +155|[Perfect Squares](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Perfect%20Squares.java) +156|[Maximum Matching of Players With Trainers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Matching%20of%20Players%20With%20Trainers.java) +157|[Word Search](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Word%20Search.java) +158|[Find Triangular Sum of an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Triangular%20Sum%20of%20an%20Array.java) +159|[Knight Dialer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Knight%20Dialer.java) +160|[3Sum Smaller](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/3Sum%20Smaller.java) +161|[Repeated DNA Sequences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Repeated%20DNA%20Sequences.java) +162|[Lowest Common Ancestor of a Binary Tree III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Lowest%20Common%20Ancestor%20of%20a%20Binary%20Tree%20III.java) +163|[Partition Array According to Given Pivot](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Partition%20Array%20According%20to%20Given%20Pivot.java) +164|[Construct K Palindrome Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Construct%20K%20Palindrome%20Strings.java) +165|[Solve the Equation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Solve%20the%20Equation.java) +166|[Average Waiting Time](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Average%20Waiting%20Time.java) +167|[Time Needed to Rearrange a Binary String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Time%20Needed%20to%20Rearrange%20a%20Binary%20String.java) +168|[Sort Integers by The Power Value](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20Integers%20by%20The%20Power%20Value.java) +169|[Sum in a Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sum%20in%20a%20Matrix.java) +170|[Combination Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Combination%20Sum.java) +171|[Make String a Subsequence Using Cyclic Increments](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Make%20String%20a%20Subsequence%20Using%20Cyclic%20Increments.java) +172|[Merge Intervals](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Merge%20Intervals.java) +173|[4 Sum II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/4%20Sum%20II.java) +174|[Advantage Shuffle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Advantage%20Shuffle.java) +175|[Number of Dice Rolls With Target Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Dice%20Rolls%20With%20Target%20Sum.java) +176|[Minimum Flips to Make a OR b Equal to c](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Flips%20to%20Make%20a%20OR%20b%20Equal%20to%20c.java) +177|[Basic Calculator II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Basic%20Calculator%20II.java) +178|[Find Original Array From Doubled Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Original%20Array%20From%20Doubled%20Array.java) +179|[Maximum Length of Repeated Subarray](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Length%20of%20Repeated%20Subarray.java) +180|[Lonely Pixel I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Lonely%20Pixel%20I.java) +181|[Guess Number Higher or Lower II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Guess%20Number%20Higher%20or%20Lower%20II.java) +182|[Remove Duplicate Letters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Duplicate%20Letters.java) +183|[Construct Binary Tree from Preorder and Inorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Construct%20Binary%20Tree%20from%20Preorder%20and%20Inorder%20Traversal.java) +184|[Group the People Given the Group Size They Belong To](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Group%20the%20People%20Given%20the%20Group%20Size%20They%20Belong%20To.java) +185|[House Robber II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/House%20Robber%20II.java) +186|[Find the Winner of an Array Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20Winner%20of%20an%20Array%20Game.java) +187|[Check if Strings Can be Made Equal With Operations II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Check%20if%20Strings%20Can%20be%20Made%20Equal%20With%20Operations%20II.java) +188|[Letter Combinations of a Phone Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Letter%20Combinations%20of%20a%20Phone%20Number.java) +189|[Implement Magic Dictionary](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Implement%20Magic%20Dictionary.java) +190|[Task Scheduler](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Task%20Scheduler.java) +191|[Minimum Size Subarray Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Size%20Subarray%20Sum.java) +192|[Max Chunks To Make Sorted](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Max%20Chunks%20To%20Make%20Sorted.java) +193|[Max Number of K-Sum Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Max%20Number%20of%20K-Sum%20Pairs.java) +194|[Longest Word in Dictionary through Deleting](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Word%20in%20Dictionary%20through%20Deleting.java) +195|[Maximum Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Binary%20Tree.java) +196|[Find and Replace in String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20and%20Replace%20in%20String.java) +197|[Sort Characters By Frequency](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20Characters%20By%20Frequency.java) +198|[Maximum Erasure Value](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Erasure%20Value.java) +199|[Number of Matching Subsequences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Matching%20Subsequences.java) +200|[Simple Bank System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Simple%20Bank%20System.java) +201|[Camelcase Matching](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Camelcase%20Matching.java) +202|[Split Array into Consecutive Subsequences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Split%20Array%20into%20Consecutive%20Subsequences.java) +203|[Integer To Roman](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Integer%20To%20Roman.java) +204|[Smallest Value of the Rearranged Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Smallest%20Value%20of%20the%20Rearranged%20Number.java) +205|[Count Servers That Communicate](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Servers%20That%20Communicate.java) +206|[Execution of All Suffix Instructions Staying in a Grid](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Execution%20of%20All%20Suffix%20Instructions%20Staying%20in%20a%20Grid.java) +207|[Number of Laser Beams in a Bank](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Laser%20Beams%20in%20a%20Bank.java) +208|[Minimize Maximum Pair Sum in Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimize%20Maximum%20Pair%20Sum%20in%20Array.java) +209|[Lowest Common Ancestor of a Binary Tree II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Lowest%20Common%20Ancestor%20of%20a%20Binary%20Tree%20II.java) +210|[Image Overlap](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Image%20Overlap.java) +211|[Balance a Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Balance%20a%20Binary%20Search%20Tree.java) +212|[Insert Greatest Common Divisors in Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Insert%20Greatest%20Common%20Divisors%20in%20Linked%20List.java) +213|[Reordered Power of 2](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reordered%20Power%20of%202.java) +214|[Construct Binary Tree from Inorder and Postorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Construct%20Binary%20Tree%20from%20Inorder%20and%20Postorder%20Traversal.java) +215|[Multiply Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Multiply%20Strings.java) +216|[K Radius Subarray Averages](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/K%20Radius%20Subarray%20Averages.java) +217|[Minimum Health to Beat Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Health%20to%20Beat%20Game.java) +218|[Path With Minimum Effort](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Path%20With%20Minimum%20Effort.java) +219|[Append K Integers With Minimal Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Append%20K%20Integers%20With%20Minimal%20Sum.java) +220|[Minimum Moves to Equal Array Elements II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Moves%20to%20Equal%20Array%20Elements%20II.java) +221|[Parallel Courses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Parallel%20Courses.java) +222|[Put Boxes Into the Warehouse I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Put%20Boxes%20Into%20the%20Warehouse%20I.java) +223|[Adding Two Negabinary Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Adding%20Two%20Negabinary%20Numbers.java) +224|[Minimum Rounds to Complete All Tasks](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Rounds%20to%20Complete%20All%20Tasks.java) +225|[Longest Happy String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Happy%20String.java) +226|[Nested List Weight Sum II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Nested%20List%20Weight%20Sum%20II.java) +227|[Range Sum Query 2D-Immutable](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Range%20Sum%20Query%202D-Immutable.java) +228|[Remove Nth Node From End of List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Nth%20Node%20From%20End%20of%20List.java) +229|[Peeking Iterator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Peeking%20Iterator.java) +230|[Subsets](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Subsets.java) +231|[Design Circular Queue](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Circular%20Queue.java) +232|[4 Keys Keyboard](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/4%20Keys%20Keyboard.java) +233|[Single Element in a Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Single%20Element%20in%20a%20Sorted%20Array.java) +234|[Permutations II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Permutations%20II.java) +235|[Knight Probability in Chessboard](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Knight%20Probability%20in%20Chessboard.java) +236|[Reachable Nodes With Restrictions](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reachable%20Nodes%20With%20Restrictions.java) +237|[Longest ZigZag Path in a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20ZigZag%20Path%20in%20a%20Binary%20Tree.java) +238|[Reduce Array Size to The Half](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reduce%20Array%20Size%20to%20The%20Half.java) +239|[Maximum Length of Pair Chain](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Length%20of%20Pair%20Chain.java) +240|[Binary Tree Vertical Order Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Vertical%20Order%20Traversal.java) +241|[Reorder Data in Log Files](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reorder%20Data%20in%20Log%20Files.java) +242|[Maximum Product Subarray](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Product%20Subarray.java) +243|[Rotate List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rotate%20List.java) +244|[Find the Celebrity](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20Celebrity.java) +245|[Swap Nodes in Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Swap%20Nodes%20in%20Pairs.java) +246|[Filter Restaurants by Vegan-Friendly, Price and Distance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Filter%20Restaurants%20by%20Vegan-Friendly,%20Price%20and%20Distance.java) +247|[Evaluate Division](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Evaluate%20Division.java) +248|[Minimum Operations to Make Array Equal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Operations%20to%20Make%20Array%20Equal.java) +249|[Combinations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Combinations.java) +250|[Max Area of Island](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Max%20Area%20of%20Island.java) +251|[Sort List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20List.java) +252|[Most Frequent Subtree Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Most%20Frequent%20Subtree%20Sum.java) +253|[Find Peak Element](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Peak%20Element.java) +254|[Open The Lock](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Open%20The%20Lock.java) +255|[Fruit Into Baskets](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Fruit%20Into%20Baskets.java) +256|[Maximum Sum of Almost Unique Subarray](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Sum%20of%20Almost%20Unique%20Subarray.java) +257|[Remove K Digits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20K%20Digits.java) +258|[Minimum Number of Steps to Make Two Strings Anagram](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Number%20of%20Steps%20to%20Make%20Two%20Strings%20Anagram.java) +259|[Connecting Cities With Minimum Cost](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Connecting%20Cities%20With%20Minimum%20Cost.java) +260|[Decoded String at Index](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Decoded%20String%20at%20Index.java) +261|[Satisfisbility of Equality Equations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Satisfisbility%20of%20Equality%20Equations.java) +262|[Maximum Product of Word Lengths](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Product%20of%20Word%20Lengths.java) +263|[Maximum Number of Integers to Choose From a Range I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Number%20of%20Integers%20to%20Choose%20From%20a%20Range%20I.java) +264|[Pour Water](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Pour%20Water.java) +265|[Gray Code](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Gray%20Code.java) +266|[Minimum Moves to Reach Target Score](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Moves%20to%20Reach%20Target%20Score.java) +267|[Encode and Decode TinyURL](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Encode%20and%20Decode%20TinyURL.java) +268|[Game of Life](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Game%20of%20Life.java) +269|[Number of Pairs of Strings With Concatenation Equal to Target](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Pairs%20of%20Strings%20With%20Concatenation%20Equal%20to%20Target.java) +270|[Maximum Swap](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Swap.java) +271|[Time Based Key-Value Store](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Time%20Based%20Key-Value%20Store.java) +272|[Compare Version Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Compare%20Version%20Numbers.java) +273|[Reverse Nodes in Even Length Groups](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reverse%20Nodes%20in%20Even%20Length%20Groups.java) +274|[Maximum Number of Vowels in a Substring of Given Length](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Number%20of%20Vowels%20in%20a%20Substring%20of%20Given%20Length.java) +275|[Graph Valid Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Graph%20Valid%20Tree.java) +276|[Minimum Operations to Reduce X to Zero](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Operations%20to%20Reduce%20X%20to%20Zero.java) +277|[Group Anagrams](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Group%20Anagrams.java) +278|[Delete the Middle Node of a Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Delete%20the%20Middle%20Node%20of%20a%20Linked%20List.java) +279|[Lowest Common Ancestor of a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Lowest%20Common%20Ancestor%20of%20a%20Binary%20Tree.java) +280|[Deepest Leaves Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Deepest%20Leaves%20Sum.java) +281|[Minimize Maximum of Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimize%20Maximum%20of%20Array.java) +282|[Boundary of Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Boundary%20of%20Binary%20Tree.java) +283|[Clone N-ary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Clone%20N-ary%20Tree.java) +284|[Rotate Image](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rotate%20Image.java) +285|[Self Dividing Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Self%20Dividing%20Numbers.java) +286|[Remove Nodes From Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Nodes%20From%20Linked%20List.java) +287|[Map Sum Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Map%20Sum%20Pairs.java) +288|[Restore the Array From Adjacent Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Restore%20the%20Array%20From%20Adjacent%20Pairs.java) +289|[Find the Index of the Large Integer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20Index%20of%20the%20Large%20Integer.java) +290|[Combination Sum IV](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Combination%20Sum%20IV.java) +291|[Pacific Atlantic Water Flow](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Pacific%20Atlantic%20Water%20Flow.java) +292|[Delete Leaves With a Given Value](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Delete%20Leaves%20With%20a%20Given%20Value.java) +293|[Pow](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Pow.java) +294|[Remove Comments](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Comments.java) +295|[Longest Uploaded Prefix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Uploaded%20Prefix.java) +296|[Rotated Digits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rotated%20Digits.java) +297|[Next Permutation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Next%20Permutation.java) +298|[Find the Substring With Maximum Cost](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20Substring%20With%20Maximum%20Cost.java) +299|[Design Log Storage System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Log%20Storage%20System.java) +300|[Decode Ways](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Decode%20Ways.java) +301|[Number of Longest Increasing Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Longest%20Increasing%20Subsequence.java) +302|[Triangle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Triangle.java) +303|[Non-overlapping Intervals](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Non-overlapping%20Intervals.java) +304|[Broken Calculator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Broken%20Calculator.java) +305|[Maximum Score from Performing Multiplication Operations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Score%20from%20Performing%20Multiplication%20Operations.java) +306|[Vowel Spellchecker](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Vowel%20Spellchecker.java) +307|[Maximum Sum of Distinct Subarrays With Length K](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Sum%20of%20Distinct%20Subarrays%20With%20Length%20K.java) +308|[4Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/4Sum.java) +309|[House Robber](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/House%20Robber.java) +310|[Find Root of N-Ary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Root%20of%20N-Ary%20Tree.java) +311|[Rotate Function](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rotate%20Function.java) +312|[Can Make Palindrome from Substring](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Can%20Make%20Palindrome%20from%20Substring.java) +313|[Find Distance in a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Distance%20in%20a%20Binary%20Tree.java) +314|[Possible Bipartition](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Possible%20Bipartition.java) +315|[Design Hit Counter](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Hit%20Counter.java) +316|[Insert into a Sorted Circular Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Insert%20into%20a%20Sorted%20Circular%20Linked%20List.java) +317|[Online Stock Span](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Online%20Stock%20Span.java) +318|[Min Cost to Connect All Points](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Min%20Cost%20to%20Connect%20All%20Points.java) +319|[Minimum Time to Collect All Apples in a Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Time%20to%20Collect%20All%20Apples%20in%20a%20Tree.java) +320|[Minimum Area Rectangle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Area%20Rectangle.java) +321|[Invalid Transactions](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Invalid%20Transactions.java) +322|[Remove All Occurrences of a Substring](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20All%20Occurrences%20of%20a%20Substring.java) +323|[Minimum Average Difference](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Average%20Difference.java) +324|[Maximal Score After Applying K Operations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximal%20Score%20After%20Applying%20K%20Operations.java) +325|[Minimum Amount of Time to Collect Garbage](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Amount%20of%20Time%20to%20Collect%20Garbage.java) +326|[Search in Rotated Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Search%20in%20Rotated%20Sorted%20Array.java) +327|[Letter Tiles Possibilities](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Letter%20Tiles%20Possibilities.java) +328|[Divide Players Into Teams of Equal Skill](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Divide%20Players%20Into%20Teams%20of%20Equal%20Skill.java) +329|[Path with Maximum Gold](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Path%20with%20Maximum%20Gold.java) +330|[Copy List with Random Pointer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Copy%20List%20with%20Random%20Pointer.java) +331|[Number of Islands](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Islands.java) +332|[Total Cost to Hire K Workers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Total%20Cost%20to%20Hire%20K%20Workers.java) +333|[Sum Multiples](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sum%20Multiples.java) +334|[Custom Sort String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Custom%20Sort%20String.java) +335|[Populating Next Right Pointers in Each Node](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Populating%20Next%20Right%20Pointers%20in%20Each%20Node.java) +336|[Mirror Reflection](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Mirror%20Reflection.java) +337|[All Possible Full Binary Trees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/All%20Possible%20Full%20Binary%20Trees.java) +338|[Maximum Total Importance of Roads](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Total%20Importance%20of%20Roads.java) +339|[Sum Root to Leaf Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sum%20Root%20to%20Leaf%20Numbers.java) +340|[Contiguous Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Contiguous%20Array.java) +341|[Large Divisble Subset](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Large%20Divisble%20Subset.java) +342|[Minimum Height Trees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Height%20Trees.java) +343|[Analyze User Website Visit Pattern](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Analyze%20User%20Website%20Visit%20Pattern.java) +344|[Partitioning Into Minimum Number Of Deci-Binary Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Partitioning%20Into%20Minimum%20Number%20Of%20Deci-Binary%20Numbers.java) +345|[Permutations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Permutations.java) +346|[Maximum Sum of an Hourglass](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Sum%20of%20an%20Hourglass.java) +347|[Minimum Fuel Cost to Report to the Capital](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Fuel%20Cost%20to%20Report%20to%20the%20Capital.java) +348|[Find the Prefix Common Array of Two Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20Prefix%20Common%20Array%20of%20Two%20Arrays.java) +349|[Coin Change 2](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Coin%20Change%202.java) +350|[Construct Quad Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Construct%20Quad%20Tree.java) +351|[Valid Parenthesis String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Valid%20Parenthesis%20String.java) +352|[Apply Discount Every n Orders](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Apply%20Discount%20Every%20n%20Orders.java) +353|[All Elements in Two Binary Search Trees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/All%20Elements%20in%20Two%20Binary%20Search%20Trees.java) +354|[Longest Substring Without Repeating Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Substring%20Without%20Repeating%20Characters.java) +355|[Fraction to Recurring Decimal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Fraction%20to%20Recurring%20Decimal.java) +356|[Extra Characters in a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Extra%20Characters%20in%20a%20String.java) +357|[Product of the Last K Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Product%20of%20the%20Last%20K%20Numbers.java) +358|[Wiggle Sort](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Wiggle%20Sort.java) +359|[Peak Index in a Mountain Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Peak%20Index%20in%20a%20Mountain%20Array.java) +360|[Accounts Merge](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Accounts%20Merge.java) +361|[K Closest Points to Origin](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/K%20Closest%20Points%20to%20Origin.java) +362|[Largest Time for Given Digits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Largest%20Time%20for%20Given%20Digits.java) +363|[Fair Distribution of Cookies](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Fair%20Distribution%20of%20Cookies.java) +364|[Count Sub Islands](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Sub%20Islands.java) +365|[Reverse Words in a String II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reverse%20Words%20in%20a%20String%20II.java) +366|[Find Leaves of Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Leaves%20of%20Binary%20Tree.java) +367|[Partition Labels](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Partition%20Labels.java) +368|[Apply Discount to Prices](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Apply%20Discount%20to%20Prices.java) +369|[Sort An Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20An%20Array.java) +370|[Hand of Straights](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Hand%20of%20Straights.java) +371|[Angle Between Hands of a Clock](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Angle%20Between%20Hands%20of%20a%20Clock.java) +372|[Maximum Star Sum of a Graph](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Star%20Sum%20of%20a%20Graph.java) +373|[Reorder List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reorder%20List.java) +374|[Find a Corresponding Node of a Binary Tree in a Clone of That Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20a%20Corresponding%20Node%20of%20a%20Binary%20Tree%20in%20a%20Clone%20of%20That%20Tree.java) +375|[Remove Colored Pieces if Both Neighbors are the Same Color](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Colored%20Pieces%20if%20Both%20Neighbors%20are%20the%20Same%20Color.java) +376|[Find Consecutive Integers from a Data Stream](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Consecutive%20Integers%20from%20a%20Data%20Stream.java) +377|[Find Eventual Safe States](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Eventual%20Safe%20States.java) +378|[Odd Even Linked Lists](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Odd%20Even%20Linked%20Lists.java) +379|[Find Right Interval](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Right%20Interval.java) +380|[Dot Product of Two Sparse Vectors](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Dot%20Product%20of%20Two%20Sparse%20Vectors.java) +381|[Minimum Number of Arrows to Burst Balloons](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Number%20of%20Arrows%20to%20Burst%20Balloons.java) +382|[Product of Two Run-Length Encoded Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Product%20of%20Two%20Run-Length%20Encoded%20Arrays.java) +383|[HTML Entity Parser](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/HTML%20Entity%20Parser.java) +384|[Find All Anagrams in a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20All%20Anagrams%20in%20a%20String.java) +385|[Boats to Save People](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Boats%20to%20Save%20People.java) +386|[Print Words Vertically](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Print%20Words%20Vertically.java) +387|[Minimum Falling Path Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Falling%20Path%20Sum.java) +388|[Strictly Palindromic Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Strictly%20Palindromic%20Number.java) +389|[Sentence Similarity III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sentence%20Similarity%20III.java) +390|[Minimum Genetic Mutation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Genetic%20Mutation.java) +391|[Split BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Split%20BST.java) +392|[Iterator for Combination](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Iterator%20for%20Combination.java) +393|[Valid Triangle Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Valid%20Triangle%20Number.java) +394|[Keys and Rooms](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Keys%20and%20Rooms.java) +395|[Interval List Intersections](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Interval%20List%20Intersections.java) +396|[Subarray Sums Divisible by K](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Subarray%20Sums%20Divisible%20by%20K.java) +397|[Merge Nodes in Between Zeros](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Merge%20Nodes%20in%20Between%20Zeros.java) +398|[Maximum Level Sum of a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Level%20Sum%20of%20a%20Binary%20Tree.java) +399|[Expressive Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Expressive%20Words.java) +400|[Friends Of Appropriate Ages](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Friends%20Of%20Appropriate%20Ages.java) +401|[Flatten Nested List Iterator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Flatten%20Nested%20List%20Iterator.java) +402|[Corporate Flight Bookings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Corporate%20Flight%20Bookings.java) +403|[Unique Binary Search Trees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Unique%20Binary%20Search%20Trees.java) +404|[Longest Increasing Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Increasing%20Subsequence.java) +405|[Design Front Middle Back Queue](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Front%20Middle%20Back%20Queue.java) +406|[Design A Leaderboard](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20A%20Leaderboard.java) +407|[Search in Rotated Sorted Array II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Search%20in%20Rotated%20Sorted%20Array%20II.java) +408|[Tuple With Same Product](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Tuple%20With%20Same%20Product.java) +409|[Delete Nodes And Return Forest](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Delete%20Nodes%20And%20Return%20Forest.java) +410|[The kth Factor of n](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/The%20kth%20Factor%20of%20n.java) +411|[Minimum Time Difference](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Time%20Difference.java) +412|[Maximum Length of Subarray With Positive Product](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Length%20of%20Subarray%20With%20Positive%20Product.java) +413|[Smallest Integer Divisible by K](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Smallest%20Integer%20Divisible%20by%20K.java) +414|[Find Players With Zero or One Losses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Players%20With%20Zero%20or%20One%20Losses.java) +415|[Min Stack](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Min%20Stack.java) +416|[Remove Zero Sum Consecutive Nodes from Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Zero%20Sum%20Consecutive%20Nodes%20from%20Linked%20List.java) +417|[Validate IP Address](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Validate%20IP%20Address.java) +418|[Reduction Operations to Make the Array Elements Equal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reduction%20Operations%20to%20Make%20the%20Array%20Elements%20Equal.java) +419|[Nearest Exit from Entrance in Maze](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Nearest%20Exit%20from%20Entrance%20in%20Maze.java) +420|[Cinema Seat Allocation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Cinema%20Seat%20Allocation.java) +421|[Delete Operation for Two Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Delete%20Operation%20for%20Two%20Strings.java) +422|[Path with Maximum Probability](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Path%20with%20Maximum%20Probability.java) +423|[Minimum Time to Complete Trips](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Time%20to%20Complete%20Trips.java) +424|[Check If All 1's Are at Least Length K Places Away](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Check%20If%20All%201's%20Are%20at%20Least%20Length%20K%20Places%20Away.java) +425|[RLE Iterator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/RLE%20Iterator.java) +426|[Increasing Subsequences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Increasing%20Subsequences.java) +427|[Number of Closed Islands](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Closed%20Islands.java) +428|[Number of Substrings With Only 1s](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Substrings%20With%20Only%201s.java) +429|[Delete Tree Nodes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Delete%20Tree%20Nodes.java) +430|[Exclusive Time of Functions](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Exclusive%20Time%20of%20Functions.java) +431|[Check If a String Is a Valid Sequence from Root to Leaves Path in a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Check%20If%20a%20String%20Is%20a%20Valid%20Sequence%20from%20Root%20to%20Leaves%20Path%20in%20a%20Binary%20Tree.java) +432|[Count Ways To Build Good Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Ways%20To%20Build%20Good%20Strings.java) +433|[Minimum Score of a Path Between Two Cities](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Score%20of%20a%20Path%20Between%20Two%20Cities.java) +434|[Leftmost Column with at Least a One](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Leftmost%20Column%20with%20at%20Least%20a%20One.java) +435|[Subsets II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Subsets%20II.java) +436|[One Edit Distance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/One%20Edit%20Distance.java) +437|[N-ary Tree Level Order Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/N-ary%20Tree%20Level%20Order%20Traversal.java) +438|[Design Snake Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Snake%20Game.java) +439|[Swap For Longest Repeated Character Substring](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Swap%20For%20Longest%20Repeated%20Character%20Substring.java) +440|[Find the Student that Will Replace the Chalk](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20Student%20that%20Will%20Replace%20the%20Chalk.java) +441|[LRU Cache](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/LRU%20Cache.java) +442|[Maximum Number of Groups Entering a Competition](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Number%20of%20Groups%20Entering%20a%20Competition.java) +443|[Container With Most Water](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Container%20With%20Most%20Water.java) +444|[Subdomain Visit Count](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Subdomain%20Visit%20Count.java) +445|[4Sum II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/4Sum%20II.java) +446|[Word Ladder](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Word%20Ladder.java) +447|[Delete Node in a BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Delete%20Node%20in%20a%20BST.java) +448|[Longest Well-Performing Interval](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Well-Performing%20Interval.java) +449|[Reconstruct Original Digits from English](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reconstruct%20Original%20Digits%20from%20English.java) +450|[Single Number II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Single%20Number%20II.java) +451|[Maximum Value after Insertion](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Value%20after%20Insertion.java) +452|[Optimal Division](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Optimal%20Division.java) +453|[Continuous Subarray Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Continuous%20Subarray%20Sum.java) +454|[Number of Operations to Make Network Connected](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Operations%20to%20Make%20Network%20Connected.java) +455|[Network Delay Time](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Network%20Delay%20Time.java) +456|[Flip Equivalent Binary Trees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Flip%20Equivalent%20Binary%20Trees.java) +457|[String to Integer (atoi)](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/String%20to%20Integer%20(atoi).java) +458|[Coin Change](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Coin%20Change.java) +459|[Max Consecutives Ones II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Max%20Consecutives%20Ones%20II.java) +460|[Kth Smallest Element in a BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Kth%20Smallest%20Element%20in%20a%20BST.java) +461|[UTF-8 Validation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/UTF-8%20Validation.java) +462|[Remove Interval](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Interval.java) +463|[Find Nearest Right Node in Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Nearest%20Right%20Node%20in%20Binary%20Tree.java) +464|[Create Binary Tree From Descriptions](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Create%20Binary%20Tree%20From%20Descriptions.java) +465|[Evaluate the Bracket Pairs of a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Evaluate%20the%20Bracket%20Pairs%20of%20a%20String.java) +466|[Wiggle Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Wiggle%20Subsequence.java) +467|[Random Pick Index](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Random%20Pick%20Index.java) +468|[Distribute Coins in Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Distribute%20Coins%20in%20Binary%20Tree.java) +469|[Sum of Even Numbers After Queries](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sum%20of%20Even%20Numbers%20After%20Queries.java) +470|[Path With Maximum Minimum Value](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Path%20With%20Maximum%20Minimum%20Value.java) +471|[Most Profit Assigning Work](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Most%20Profit%20Assigning%20Work.java) +472|[The Number of Weak Characters in the Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/The%20Number%20of%20Weak%20Characters%20in%20the%20Game.java) +473|[Partition List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Partition%20List.java) +474|[Number of Distinct Islands](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Distinct%20Islands.java) +475|[Design Circular Deque](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Circular%20Deque.java) +476|[Implement Trie (Prefix Tree)](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Implement%20Trie%20(Prefix%20Tree).java) +477|[Maximize Number of Subsequences in a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximize%20Number%20of%20Subsequences%20in%20a%20String.java) +478|[Max Sum of a Pair With Equal Sum of Digits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Max%20Sum%20of%20a%20Pair%20With%20Equal%20Sum%20of%20Digits.java) +479|[Number of Provinces](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Provinces.java) +480|[Largest BST Subtree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Largest%20BST%20Subtree.java) +481|[Range Sum Query - Mutable](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Range%20Sum%20Query%20-%20Mutable.java) +482|[Mini Parser](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Mini%20Parser.java) +483|[Number of Smooth Descent Periods of a Stock](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Smooth%20Descent%20Periods%20of%20a%20Stock.java) +484|[Maximum Distance Between a Pair of Values](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Distance%20Between%20a%20Pair%20of%20Values.java) +485|[Alert Using Same Key-Card Three or More Times in a One Hour Period](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Alert%20Using%20Same%20Key-Card%20Three%20or%20More%20Times%20in%20a%20One%20Hour%20Period.java) +486|[Linked List Components](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Linked%20List%20Components.java) +487|[Binary Tree Upside Down](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Upside%20Down.java) +488|[New 21 Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/New%2021%20Game.java) +489|[Max Increase to Keep City Skyline](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Max%20Increase%20to%20Keep%20City%20Skyline.java) +490|[Daily Temperatures](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Daily%20Temperatures.java) +491|[Binary Search Tree to Greater Sum Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Search%20Tree%20to%20Greater%20Sum%20Tree.java) +492|[Subarray Product Less Than K](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Subarray%20Product%20Less%20Than%20K.java) +493|[Design a Stack With Increment Operation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20a%20Stack%20With%20Increment%20Operation.java) +494|[Break a Palindrome](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Break%20a%20Palindrome.java) +495|[Maximum Size Subarray Sum Equals k](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Size%20Subarray%20Sum%20Equals%20k.java) +496|[Minimum Number of Steps to Make Two Strings Anagram II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Number%20of%20Steps%20to%20Make%20Two%20Strings%20Anagram%20II.java) +497|[Subarray Sum Equals K](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Subarray%20Sum%20Equals%20K.java) +498|[Car Pooling](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Car%20Pooling.java) +499|[Remove Sub-Folders from the Filesystem](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Sub-Folders%20from%20the%20Filesystem.java) +500|[Sum of Nodes with Even-Valued Grandparent](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sum%20of%20Nodes%20with%20Even-Valued%20Grandparent.java) +501|[Check If a String Can Break Another String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Check%20If%20a%20String%20Can%20Break%20Another%20String.java) +502|[Ternary Expression Parser](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Ternary%20Expression%20Parser.java) +503|[Generate Parentheses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Generate%20Parentheses.java) +504|[Minimum Penalty for a Shop](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Penalty%20for%20a%20Shop.java) +505|[Encode and Decode Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Encode%20and%20Decode%20Strings.java) +506|[Asteroid Collision](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Asteroid%20Collision.java) +507|[Minimum Deletion Cost to Avoid Repeating Letters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Deletion%20Cost%20to%20Avoid%20Repeating%20Letters.java) +508|[Design Phone Directory](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Phone%20Directory.java) +509|[Remove Duplicates from Sorted List II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Duplicates%20from%20Sorted%20List%20II.java) +510|[Count Nodes Equal to Sum of Descendants](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Nodes%20Equal%20to%20Sum%20of%20Descendants.java) +511|[Random Pick With Weight](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Random%20Pick%20With%20Weight.java) +512|[Maximize the Topmost Element After K Moves](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximize%20the%20Topmost%20Element%20After%20K%20Moves.java) +513|[Swapping Nodes in a Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Swapping%20Nodes%20in%20a%20Linked%20List.java) +514|[Number of Subsequences That Satisfy the Given Sum Condition](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Subsequences%20That%20Satisfy%20the%20Given%20Sum%20Condition.java) +515|[Ones and Zeroes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Ones%20and%20Zeroes.java) +516|[Number of Connected Components in an Undirected Graph](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Connected%20Components%20in%20an%20Undirected%20Graph.java) +517|[Display Table of Food Orders in a Restaurant](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Display%20Table%20of%20Food%20Orders%20in%20a%20Restaurant.java) +518|[Campus Bikes II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Campus%20Bikes%20II.java) +519|[Longest Line of Consecutive One in Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Line%20of%20Consecutive%20One%20in%20Matrix.java) +520|[Zigzag Iterator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Zigzag%20Iterator.java) +521|[Merge In Between Linked Lists](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Merge%20In%20Between%20Linked%20Lists.java) +522|[Surrounded Regions](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Surrounded%20Regions.java) +523|[Seat Reservation Manager](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Seat%20Reservation%20Manager.java) +524|[Print Immutable Linked List in Reverse](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Print%20Immutable%20Linked%20List%20in%20Reverse.java) +525|[Tree Diameter](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Tree%20Diameter.java) +526|[Incremental Memory Leak](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Incremental%20Memory%20Leak.java) +527|[Lexicographically Smallest Equivalent String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Lexicographically%20Smallest%20Equivalent%20String.java) +528|[Reverse Words in a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reverse%20Words%20in%20a%20String.java) +529|[Simplify Path](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Simplify%20Path.java) +530|[Design Underground System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Underground%20System.java) +531|[Sequential Digits](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sequential%20Digits.java) +532|[Longest Substring with At Most Two Distinct Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Substring%20with%20At%20Most%20Two%20Distinct%20Characters.java) +533|[Smallest String With Swaps](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Smallest%20String%20With%20Swaps.java) +534|[Jump Game III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Jump%20Game%20III.java) +535|[Adding Spaces to a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Adding%20Spaces%20to%20a%20String.java) +536|[Shortest Path with Alternating Colors](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Shortest%20Path%20with%20Alternating%20Colors.java) +537|[Maximum Subarray](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Subarray.java) +538|[Removing Stars From a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Removing%20Stars%20From%20a%20String.java) +539|[Find K Pairs with Smallest Sums](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20K%20Pairs%20with%20Smallest%20Sums.java) +540|[Check if There is a Valid Path in a Grid](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Check%20if%20There%20is%20a%20Valid%20Path%20in%20a%20Grid.java) +541|[Tweet Counts Per Frequency](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Tweet%20Counts%20Per%20Frequency.java) +542|[Ugly Number II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Ugly%20Number%20II.java) +543|[Find First and Last Position of Element in Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20First%20and%20Last%20Position%20of%20Element%20in%20Sorted%20Array.java) +544|[Longest Subarray of 1's After Deleting One Element](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Subarray%20of%201's%20After%20Deleting%20One%20Element.java) +545|[Clone Binary Tree With Random Pointer](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Clone%20Binary%20Tree%20With%20Random%20Pointer.java) +546|[Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Continuous%20Subarray%20With%20Absolute%20Diff%20Less%20Than%20or%20Equal%20to%20Limit.java) +547|[Count Number of Bad Pairs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Number%20of%20Bad%20Pairs.java) +548|[Super Ugly Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Super%20Ugly%20Number.java) +549|[Add Two Numbers II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Add%20Two%20Numbers%20II.java) +550|[Implement Rand10() Using Rand7()](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Implement%20Rand10()%20Using%20Rand7().java) +551|[Minimum Deletions to Make Character Frequencies Unique](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Deletions%20to%20Make%20Character%20Frequencies%20Unique.java) +552|[Maximum Area of a Piece of Cake After Horizontal and Vertical Cuts](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Area%20of%20a%20Piece%20of%20Cake%20After%20Horizontal%20and%20Vertical%20Cuts.java) +553|[Array Nesting](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Array%20Nesting.java) +554|[Valid Square](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Valid%20Square.java) +555|[Find Closest Node to Given Two Nodes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Closest%20Node%20to%20Given%20Two%20Nodes.java) +556|[Course Schedule](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Course%20Schedule.java) +557|[The k Strongest Values in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/The%20k%20Strongest%20Values%20in%20an%20Array.java) +558|[Longest Arithmetic Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Arithmetic%20Subsequence.java) +559|[Optimal Partition of String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Optimal%20Partition%20of%20String.java) +560|[Maximum Bags With Full Capacity of Rocks](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Bags%20With%20Full%20Capacity%20of%20Rocks.java) +561|[Path Sum II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Path%20Sum%20II.java) +562|[Unique Paths](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Unique%20Paths.java) +563|[Replace Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Replace%20Words.java) +564|[Rank Teams by Votes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rank%20Teams%20by%20Votes.java) +565|[Determine if a Cell Is Reachable at a Given Time](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Determine%20if%20a%20Cell%20Is%20Reachable%20at%20a%20Given%20Time.java) +566|[Jump Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Jump%20Game.java) +567|[Can Convert String in K Moves](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Can%20Convert%20String%20in%20K%20Moves.java) +568|[Least Number of Unique Integers after K Removals](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Least%20Number%20of%20Unique%20Integers%20after%20K%20Removals.java) +569|[Sum of Absolute Differences in a Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sum%20of%20Absolute%20Differences%20in%20a%20Sorted%20Array.java) +570|[Determine the Minimum Sum of a k-avoiding Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Determine%20the%20Minimum%20Sum%20of%20a%20k-avoiding%20Array.java) +571|[Linked List Random Node](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Linked%20List%20Random%20Node.java) +572|[Valid Tic-Tac-Toe State](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Valid%20Tic-Tac-Toe%20State.java) +573|[Increasing Triplet Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Increasing%20Triplet%20Subsequence.java) +574|[Partition Equal Subset Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Partition%20Equal%20Subset%20Sum.java) +575|[Range Addition](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Range%20Addition.java) +576|[Next Greater Numerically Balanced Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Next%20Greater%20Numerically%20Balanced%20Number.java) +577|[Interleaving String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Interleaving%20String.java) +578|[String Compression](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/String%20Compression.java) +579|[Insert Into a Cyclic Sorted List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Insert%20Into%20a%20Cyclic%20Sorted%20List.java) +580|[Count Submatrices With All Ones](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Submatrices%20With%20All%20Ones.java) +581|[Shuffle an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Shuffle%20an%20Array.java) +582|[Battleships in a board](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Battleships%20in%20a%20board.java) +583|[Shortest Path in Binary Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Shortest%20Path%20in%20Binary%20Matrix.java) +584|[Brace Expansion](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Brace%20Expansion.java) +585|[Complex Number Multiplication](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Complex%20Number%20Multiplication.java) +586|[Queries on a Permutation With Key](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Queries%20on%20a%20Permutation%20With%20Key.java) +587|[Find Duplicate Subtrees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Duplicate%20Subtrees.java) +588|[Maximum Ice Cream Bars](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Ice%20Cream%20Bars.java) +589|[Recover Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Recover%20Binary%20Search%20Tree.java) +590|[My Calendar I](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/My%20Calendar%20I.java) +591|[Reorder Routes to Make All Paths Lead to the City Zero](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reorder%20Routes%20to%20Make%20All%20Paths%20Lead%20to%20the%20City%20Zero.java) +592|[Maximize the Confusion of an Exam](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximize%20the%20Confusion%20of%20an%20Exam.java) +593|[Evaluate Reverse Polish Notation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Evaluate%20Reverse%20Polish%20Notation.java) +594|[Maximum Width Ramp](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Width%20Ramp.java) +595|[Number of Sub-arrays of Size K and Average Greater than or Equal to Threshold](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Sub-arrays%20of%20Size%20K%20and%20Average%20Greater%20than%20or%20Equal%20to%20Threshold.java) +596|[Range Sum of Sorted Subarray Sums](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Range%20Sum%20of%20Sorted%20Subarray%20Sums.java) +597|[Find The Original Array of Prefix Xor](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20The%20Original%20Array%20of%20Prefix%20Xor.java) +598|[Bomb Enemy](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Bomb%20Enemy.java) +599|[Find Center of Star Graph](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Center%20of%20Star%20Graph.java) +600|[Add Bold Tag in String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Add%20Bold%20Tag%20in%20String.java) +601|[Reverse Linked List II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reverse%20Linked%20List%20II.java) +602|[Permutation in String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Permutation%20in%20String.java) +603|[Sum of Numbers With Units Digit K](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sum%20of%20Numbers%20With%20Units%20Digit%20K.java) +604|[Two Sum II - Input Array Is Sorted](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Two%20Sum%20II%20-%20Input%20Array%20Is%20Sorted.java) +605|[Maximum Number of Events That Can Be Attended](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Number%20of%20Events%20That%20Can%20Be%20Attended.java) +606|[Shortest Word Distance III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Shortest%20Word%20Distance%20III.java) +607|[Sender With Largest Word Count](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sender%20With%20Largest%20Word%20Count.java) +608|[Short Encoding of Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Short%20Encoding%20of%20Words.java) +609|[Serialize and Deserialize BST](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Serialize%20and%20Deserialize%20BST.java) +610|[Remove All Ones With Row and Column Flips II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20All%20Ones%20With%20Row%20and%20Column%20Flips%20II.java) +611|[Minimum Domino Rotations For Equal Row](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Domino%20Rotations%20For%20Equal%20Row.java) +612|[132 Pattern](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/132%20Pattern.java) +613|[Remove All Adjacent Duplicates in String II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20All%20Adjacent%20Duplicates%20in%20String%20II.java) +614|[Insertion Sort List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Insertion%20Sort%20List.java) +615|[Length of the Longest Alphabetical Continuous Substring](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Length%20of%20the%20Longest%20Alphabetical%20Continuous%20Substring.java) +616|[Find the Duplicate Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20Duplicate%20Number.java) +617|[Replace Elements in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Replace%20Elements%20in%20an%20Array.java) +618|[Design Twitter](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Twitter.java) +619|[Last Moment Before All Ants Fall Out of a Plank](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Last%20Moment%20Before%20All%20Ants%20Fall%20Out%20of%20a%20Plank.java) +620|[Sentence Similarity II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sentence%20Similarity%20II.java) +621|[Count Number of Distinct Integers After Reverse Operations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Number%20of%20Distinct%20Integers%20After%20Reverse%20Operations.java) +622|[Find the Index of the First Occurrence in a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20Index%20of%20the%20First%20Occurrence%20in%20a%20String.java) +623|[Last Stone Weight II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Last%20Stone%20Weight%20II.java) +624|[Rectangle Area](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rectangle%20Area.java) +625|[My Calendar II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/My%20Calendar%20II.java) +626|[Find All Possible Recipes from Given Supplies](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20All%20Possible%20Recipes%20from%20Given%20Supplies.java) +627|[Maximum Value at a Given Index in a Bounded Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Value%20at%20a%20Given%20Index%20in%20a%20Bounded%20Array.java) +628|[Number of Distinct Substrings in a String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Distinct%20Substrings%20in%20a%20String.java) +629|[Search Suggestions System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Search%20Suggestions%20System.java) +630|[Subrectangle Queries](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Subrectangle%20Queries.java) +631|[Sort the Matrix Diagonally](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20the%20Matrix%20Diagonally.java) +632|[Convert Sorted List to Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Convert%20Sorted%20List%20to%20Binary%20Search%20Tree.java) +633|[Count Nodes Equal to Average of Subtree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Nodes%20Equal%20to%20Average%20of%20Subtree.java) +634|[Bulb Switcher](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Bulb%20Switcher.java) +635|[Verify Preorder Serialization of a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Verify%20Preorder%20Serialization%20of%20a%20Binary%20Tree.java) +636|[Minimum Speed to Arrive on Time](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Speed%20to%20Arrive%20on%20Time.java) +637|[Inorder Successor in BST II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Inorder%20Successor%20in%20BST%20II.java) +638|[Detonate the Maximum Bombs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Detonate%20the%20Maximum%20Bombs.java) +639|[Add Minimum Number of Rungs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Add%20Minimum%20Number%20of%20Rungs.java) +640|[Lexicographically Smallest String After Substring Operation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Lexicographically%20Smallest%20String%20After%20Substring%20Operation.java) +641|[Find the City With the Smallest Number of Neighbors at a Threshold Distance](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20City%20With%20the%20Smallest%20Number%20of%20Neighbors%20at%20a%20Threshold%20Distance.java) +642|[Node With Highest Edge Score](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Node%20With%20Highest%20Edge%20Score.java) +643|[Output Contest Matches](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Output%20Contest%20Matches.java) +644|[Design an Expression Tree With Evaluate Function](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20an%20Expression%20Tree%20With%20Evaluate%20Function.java) +645|[H-Index](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/H-Index.java) +646|[Best Time to Buy and Sell Stock with Cooldown](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Best%20Time%20to%20Buy%20and%20Sell%20Stock%20with%20Cooldown.java) +647|[Rabbits in Forest](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rabbits%20in%20Forest.java) +648|[Count Univalue Subtrees](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Univalue%20Subtrees.java) +649|[Find Elements in a Contaminated Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Elements%20in%20a%20Contaminated%20Binary%20Tree.java) +650|[Next Greater Node In Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Next%20Greater%20Node%20In%20Linked%20List.java) +651|[Maximum Nesting Depth of Two Valid Parentheses Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Nesting%20Depth%20of%20Two%20Valid%20Parentheses%20Strings.java) +652|[Find and Replace Pattern](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20and%20Replace%20Pattern.java) +653|[Design File System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20File%20System.java) +654|[Determine if Two Strings Are Close](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Determine%20if%20Two%20Strings%20Are%20Close.java) +655|[Maximum Absolute Sum of Any Subarray](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Absolute%20Sum%20of%20Any%20Subarray.java) +656|[Number of Pairs of Interchangeable Rectangles](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Pairs%20of%20Interchangeable%20Rectangles.java) +657|[Kth Largest Element in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Kth%20Largest%20Element%20in%20an%20Array.java) +658|[The Number of Full Rounds You Have Played](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/The%20Number%20of%20Full%20Rounds%20You%20Have%20Played.java) +659|[Snapshot Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Snapshot%20Array.java) +660|[Top K Frequent Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Top%20K%20Frequent%20Elements.java) +661|[Smallest Subtree with all the Deepest Nodes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Smallest%20Subtree%20with%20all%20the%20Deepest%20Nodes.java) +662|[Maximal Network Rank](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximal%20Network%20Rank.java) +663|[Rearrange Array Elements by Sign](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rearrange%20Array%20Elements%20by%20Sign.java) +664|[Kth Smallest Element in a Sorted Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Kth%20Smallest%20Element%20in%20a%20Sorted%20Matrix.java) +665|[Two City Scheduling](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Two%20City%20Scheduling.java) +666|[Minimum Score Triangulation of Polygon](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Score%20Triangulation%20of%20Polygon.java) +667|[Binary Tree Coloring Game](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Coloring%20Game.java) +668|[Maximum Difference Between Node and Ancestor](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Difference%20Between%20Node%20and%20Ancestor.java) +669|[Sum of Beauty of All Substrings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sum%20of%20Beauty%20of%20All%20Substrings.java) +670|[Push Dominoes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Push%20Dominoes.java) +671|[Combination Sum III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Combination%20Sum%20III.java) +672|[Find K Closest Elements](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20K%20Closest%20Elements.java) +673|[01 Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/01%20Matrix.java) +674|[Clone Graph](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Clone%20Graph.java) +675|[Longest Palindromic Substring](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Palindromic%20Substring.java) +676|[Robot Bounded In Circle](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Robot%20Bounded%20In%20Circle.java) +677|[Minimum Deletions to Make Array Beautiful](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Deletions%20to%20Make%20Array%20Beautiful.java) +678|[Koko Eating Bananas](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Koko%20Eating%20Bananas.java) +679|[Statistics from a Large Sample](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Statistics%20from%20a%20Large%20Sample.java) +680|[Insert Delete GetRandom O(1)](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Insert%20Delete%20GetRandom%20O(1).java) +681|[Longest Substring with At Most K Distinct Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Substring%20with%20At%20Most%20K%20Distinct%20Characters.java) +682|[Minimum Swaps to Group All 1's Together](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Swaps%20to%20Group%20All%201's%20Together.java) +683|[Path Sum III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Path%20Sum%20III.java) +684|[Snakes and Ladders](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Snakes%20and%20Ladders.java) +685|[Longest Palindromic Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Palindromic%20Subsequence.java) +686|[Longest String Chain](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20String%20Chain.java) +687|[Buildings With an Ocean View](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Buildings%20With%20an%20Ocean%20View.java) +688|[Sort Transformed Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20Transformed%20Array.java) +689|[Search in a Sorted Array of Unknown Size](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Search%20in%20a%20Sorted%20Array%20of%20Unknown%20Size.java) +690|[Minimize Product Sum of Two Arrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimize%20Product%20Sum%20of%20Two%20Arrays.java) +691|[Count Complete Tree Nodes](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Complete%20Tree%20Nodes.java) +692|[Minesweeper](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minesweeper.java) +693|[Best Time to Buy and Sell Stock with Transaction Fee](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Best%20Time%20to%20Buy%20and%20Sell%20Stock%20with%20Transaction%20Fee.java) +694|[Online Election](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Online%20Election.java) +695|[Minimum Cost For Tickets](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Cost%20For%20Tickets.java) +696|[Find K-Length Substrings With No Repeated Characters](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20K-Length%20Substrings%20With%20No%20Repeated%20Characters.java) +697|[Pow(x, n)](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Pow(x,%20n).java) +698|[Construct String With Repeat Limit](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Construct%20String%20With%20Repeat%20Limit.java) +699|[Word Break](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Word%20Break.java) +700|[Reverse Odd Levels of Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reverse%20Odd%20Levels%20of%20Binary%20Tree.java) +701|[Design SQL](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20SQL.java) +702|[Find the Kth Largest Integer in the Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20Kth%20Largest%20Integer%20in%20the%20Array.java) +703|[Flatten Binary Tree to Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Flatten%20Binary%20Tree%20to%20Linked%20List.java) +704|[Sort Colors](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20Colors.java) +705|[Best Time to Buy and Sell Stock II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Best%20Time%20to%20Buy%20and%20Sell%20Stock%20II.java) +706|[Longest Absolute File Path](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Longest%20Absolute%20File%20Path.java) +707|[Count Unreachable Pairs of Nodes in an Undirected Graph](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Unreachable%20Pairs%20of%20Nodes%20in%20an%20Undirected%20Graph.java) +708|[Prison Cells After N Days](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Prison%20Cells%20After%20N%20Days.java) +709|[Insert into a Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Insert%20into%20a%20Binary%20Search%20Tree.java) +710|[Binary Search Tree Iterator II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Search%20Tree%20Iterator%20II.java) +711|[Course Schedule II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Course%20Schedule%20II.java) +712|[Remove Duplicates From Sorted Array II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Duplicates%20From%20Sorted%20Array%20II.java) +713|[Shortest Bridge](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Shortest%20Bridge.java) +714|[Binary Search Tree Iterator](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Search%20Tree%20Iterator.java) +715|[Find Duplicate File in System](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Duplicate%20File%20in%20System.java) +716|[Insufficient Nodes in Root to Leaf Paths](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Insufficient%20Nodes%20in%20Root%20to%20Leaf%20Paths.java) +717|[Divide Array in Sets of K Consecutive Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Divide%20Array%20in%20Sets%20of%20K%20Consecutive%20Numbers.java) +718|[Check Completeness of a Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Check%20Completeness%20of%20a%20Binary%20Tree.java) +719|[Two Sum BSTs](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Two%20Sum%20BSTs.java) +720|[Count Sorted Vowel Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Sorted%20Vowel%20Strings.java) +721|[Check If a String Contains All Binary Codes of Size K](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Check%20If%20a%20String%20Contains%20All%20Binary%20Codes%20of%20Size%20K.java) +722|[Contains Duplicate III](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Contains%20Duplicate%20III.java) +723|[Stock Price Fluctuation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Stock%20Price%20Fluctuation.java) +724|[Spiral Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Spiral%20Matrix.java) +725|[Next Closest Time](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Next%20Closest%20Time.java) +726|[Find the Maximum Divisibility Score](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20Maximum%20Divisibility%20Score.java) +727|[Group Shifted Strings](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Group%20Shifted%20Strings.java) +728|[Array Circular Loop](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Array%20Circular%20Loop.java) +729|[ZigZag Conversion](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/ZigZag%20Conversion.java) +730|[Find the Score of All Prefixes of an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20Score%20of%20All%20Prefixes%20of%20an%20Array.java) +731|[Number of Matching Subsequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Matching%20Subsequence.java) +732|[All Paths From Source to Target](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/All%20Paths%20From%20Source%20to%20Target.java) +733|[Spiral Matrix II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Spiral%20Matrix%20II.java) +734|[Design Authentication Manager](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Authentication%20Manager.java) +735|[Minimum Operations to Make a Special Number](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Operations%20to%20Make%20a%20Special%20Number.java) +736|[People Whose List of Favorite Companies Is Not a Subset of Another List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/People%20Whose%20List%20of%20Favorite%20Companies%20Is%20Not%20a%20Subset%20of%20Another%20List.java) +737|[Number of Enclaves](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Enclaves.java) +738|[Sort the Students by Their Kth Score](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Sort%20the%20Students%20by%20Their%20Kth%20Score.java) +739|[Number of Zero-Filled Subarrays](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Number%20of%20Zero-Filled%20Subarrays.java) +740|[Bag of Tokens](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Bag%20of%20Tokens.java) +741|[Binary Tree Longest Consecutive Sequence](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Longest%20Consecutive%20Sequence.java) +742|[All Paths from Source Lead to Destination](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/All%20Paths%20from%20Source%20Lead%20to%20Destination.java) +743|[Trim a Binary Search Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Trim%20a%20Binary%20Search%20Tree.java) +744|[Lexicographical Numbers](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Lexicographical%20Numbers.java) +745|[Minimum Time to Make Rope Colorful](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Minimum%20Time%20to%20Make%20Rope%20Colorful.java) +746|[Rotate Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rotate%20Array.java) +747|[Unique Word Abbrevation](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Unique%20Word%20Abbrevation.java) +748|[Binary Tree Right Side View](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Binary%20Tree%20Right%20Side%20View.java) +749|[Solving Questions With Brainpower](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Solving%20Questions%20With%20Brainpower.java) +750|[All Nodes Distance K in Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/All%20Nodes%20Distance%20K%20in%20Binary%20Tree.java) +751|[Queue Reconstruction By Height](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Queue%20Reconstruction%20By%20Height.java) +752|[Step-By-Step Directions From a Binary Tree Node to Another](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Step-By-Step%20Directions%20From%20a%20Binary%20Tree%20Node%20to%20Another.java) +753|[Medium](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Medium.md) +754|[Meeting Rooms II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Meeting%20Rooms%20II.java) +755|[Maximum Binary Tree II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Binary%20Tree%20II.java) +756|[Maximum Subsequence Score](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Subsequence%20Score.java) +757|[Smallest String With A Given Numeric Value](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Smallest%20String%20With%20A%20Given%20Numeric%20Value.java) +758|[Print Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Print%20Binary%20Tree.java) +759|[Find Missing Observations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20Missing%20Observations.java) +760|[Restore IP Address](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Restore%20IP%20Address.java) +761|[Water & Jug Problem](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Water%20&%20Jug%20Problem.java) +762|[Maximum Width of Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Width%20of%20Binary%20Tree.java) +763|[Target Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Target%20Sum.java) +764|[Find the Longest Semi-Repetitive Substring](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20Longest%20Semi-Repetitive%20Substring.java) +765|[Synonymous Sentences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Synonymous%20Sentences.java) +766|[Top K Frequent Words](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Top%20K%20Frequent%20Words.java) +767|[Convert an Array Into a 2D Array With Conditions](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Convert%20an%20Array%20Into%20a%202D%20Array%20With%20Conditions.java) +768|[Shortest Unsorted Continuous Subarray](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Shortest%20Unsorted%20Continuous%20Subarray.java) +769|[Satisfiability of Equality Equations](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Satisfiability%20of%20Equality%20Equations.java) +770|[All Ancestors of a Node in a Directed Acyclic Graph](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/All%20Ancestors%20of%20a%20Node%20in%20a%20Directed%20Acyclic%20Graph.java) +771|[Maximize Distance to Closest Person](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximize%20Distance%20to%20Closest%20Person.java) +772|[Design Tic-Tac-Toe](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Design%20Tic-Tac-Toe.java) +773|[H-Index II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/H-Index%20II.java) +774|[3Sum](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/3Sum.java) +775|[Maximum Consecutive Floors Without Special Floors](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20Consecutive%20Floors%20Without%20Special%20Floors.java) +776|[Reorganize String](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reorganize%20String.java) +777|[Reverse Substrings Between Each Pair of Parentheses](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Reverse%20Substrings%20Between%20Each%20Pair%20of%20Parentheses.java) +778|[Maximum XOR of Two Numbers in an Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Maximum%20XOR%20of%20Two%20Numbers%20in%20an%20Array.java) +779|[Count Good Nodes in Binary Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Good%20Nodes%20in%20Binary%20Tree.java) +780|[Find the Minimum and Maximum Number of Nodes Between Critical Points](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Find%20the%20Minimum%20and%20Maximum%20Number%20of%20Nodes%20Between%20Critical%20Points.java) +781|[Missing Element in Sorted Array](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Missing%20Element%20in%20Sorted%20Array.java) +782|[Even Odd Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Even%20Odd%20Tree.java) +783|[Rearrange Array to Maximize Prefix Score](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Rearrange%20Array%20to%20Maximize%20Prefix%20Score.java) +784|[Search for a range](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Search%20for%20a%20range.java) +785|[Count Collisions on a Road](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Count%20Collisions%20on%20a%20Road.java) +786|[Numbers With Same Consecutive Differences](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Numbers%20With%20Same%20Consecutive%20Differences.java) +787|[Remove Duplicates From an Unsorted Linked List](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Remove%20Duplicates%20From%20an%20Unsorted%20Linked%20List.java) +788|[Populating Next Right Pointers in Each Node II](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Populating%20Next%20Right%20Pointers%20in%20Each%20Node%20II.java) +789|[Construct Binary Search Tree from Preorder Traversal](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Construct%20Binary%20Search%20Tree%20from%20Preorder%20Traversal.java) +790|[Shortest Completing Word](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Shortest%20Completing%20Word.java) +791|[Search a 2D Matrix](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Search%20a%202D%20Matrix.java) +792|[Add One Row to Tree](https://github.com/varunu28/LeetCode-Java-Solutions/tree/master/Medium/Add%20One%20Row%20to%20Tree.java) diff --git a/Medium/RLE Iterator.java b/Medium/RLE Iterator.java index 2c1f7683..7baf4e97 100644 --- a/Medium/RLE Iterator.java +++ b/Medium/RLE Iterator.java @@ -1,42 +1,31 @@ class RLEIterator { - int[] arr; - int idx; - int len; - public RLEIterator(int[] A) { - arr = A; - idx = 0; - len = A.length; - } - - public int next(int n) { - while (idx < len - 1 && (arr[idx] - n) < 0) { - n -= arr[idx] > 0 ? arr[idx] : 0; - updateIdx(); - - if (idx >= len - 1) { - return -1; - } - } - - if (idx < len - 1 && arr[idx] > 0) { - if (arr[idx] - n >= 0) { - int temp = arr[idx+1]; - arr[idx] -= n; - - return temp; - } - } - + + int[] encoding; + int currCounterIdx; + + public RLEIterator(int[] encoding) { + this.encoding = encoding; + this.currCounterIdx = 0; + } + + public int next(int n) { + while (n > 0) { + while (this.encoding[this.currCounterIdx] == 0 && this.currCounterIdx + 2 < this.encoding.length) { + this.currCounterIdx += 2; + } + if (this.encoding[this.currCounterIdx] == 0) { return -1; + } + int diff = Math.min(this.encoding[this.currCounterIdx], n); + this.encoding[this.currCounterIdx] -= diff; + n -= diff; } - - private void updateIdx() { - idx += 2; - } + return this.encoding[this.currCounterIdx + 1]; + } } /** * Your RLEIterator object will be instantiated and called as such: - * RLEIterator obj = new RLEIterator(A); + * RLEIterator obj = new RLEIterator(encoding); * int param_1 = obj.next(n); */ diff --git a/Medium/Random Pick With Weight.java b/Medium/Random Pick With Weight.java index 3d3546fa..e620ec63 100644 --- a/Medium/Random Pick With Weight.java +++ b/Medium/Random Pick With Weight.java @@ -1,24 +1,30 @@ class Solution { - int[] arr; - int counter = 0; - Random r = new Random(); + private int[] prefixSum; + private int totalPrefixSum; + public Solution(int[] w) { - arr = new int[w.length]; - counter += w[0]; - arr[0] = w[0]; - for (int i = 1; i < w.length; i++) { - arr[i] = arr[i - 1] + w[i]; - counter += w[i]; + this.prefixSum = new int[w.length]; + int currPrefixSum = 0; + for (int i = 0; i < w.length; i++) { + currPrefixSum += w[i]; + this.prefixSum[i] = currPrefixSum; } + this.totalPrefixSum = currPrefixSum; } public int pickIndex() { - int idx = r.nextInt(counter) + 1; - int ret = Arrays.binarySearch(arr, idx); - if(ret < 0) { - ret = -ret - 1; + double randomTarget = this.totalPrefixSum * Math.random(); + int left = 0; + int right = this.prefixSum.length; + while (left < right) { + int mid = left + (right - left) / 2; + if (randomTarget > this.prefixSum[mid]) { + left = mid + 1; + } else { + right = mid; + } } - return ret; + return left; } } diff --git a/Medium/Range Sum Query - Mutable.java b/Medium/Range Sum Query - Mutable.java index 0ff8bbbb..d57769f2 100644 --- a/Medium/Range Sum Query - Mutable.java +++ b/Medium/Range Sum Query - Mutable.java @@ -1,71 +1,55 @@ class NumArray { - int[] fen; - int[] nums; - int n; - public NumArray(int[] nums) { - this.nums = nums; - n = nums.length; - fen = new int[n + 1]; - init(); - } - - private void init () { - if (n == 0) { - return; - } - - // Compute the pre-sum - fen[1] = nums[0]; - for (int i = 1; i < n; i++) { - fen[i + 1] = fen[i] + nums[i]; - } - - for (int i = n; i > 0; i--) { - // Removing the value of parent for each node - int parent = i - (i & -i); - if (parent >= 0) { - fen[i] -= fen[parent]; - } - } - } - - public void update(int i, int val) { - // Find the difference between previous and current value - int extra = val - nums[i]; - // Update the actual array with the new val - nums[i] = val; - - // Update the tree with the extra value to all the parents - increment(i, extra); + private BIT bit; + private int[] nums; + + public NumArray(int[] nums) { + this.bit = new BIT(nums.length); + this.nums = nums; + for (int i = 0; i < nums.length; i++) { + this.bit.update(i + 1, nums[i]); } - - private void increment (int i, int extra) { - i++; - while (i <= n) { - fen[i] += extra; - i = i + (i & -i); - } + } + + public void update(int index, int val) { + int delta = val - nums[index]; + this.bit.update(index + 1, delta); + this.nums[index] = val; + } + + public int sumRange(int left, int right) { + return this.bit.query(right + 1) - this.bit.query(left); + } + + private static class BIT { + + private int[] sum; + + public BIT(int n) { + this.sum = new int[n + 1]; } - - public int sumRange(int i, int j) { - // Similar to pre sum from 0 to j - pre sum from 0 to i - return getSum(j + 1) - getSum(i); + + private void update(int idx, int delta) { + while (idx < sum.length) { + sum[idx] += delta; + idx += (idx & -idx); + } } - - private int getSum (int i) { - int res = 0; - while (i > 0) { - res += fen[i]; - i = i - (i & -i); - } - - return res; + + private int query(int idx) { + int result = 0; + while (idx > 0) { + result += sum[idx]; + idx -= (idx & -idx); + } + return result; } + } } + /** * Your NumArray object will be instantiated and called as such: * NumArray obj = new NumArray(nums); - * obj.update(i,val); - * int param_2 = obj.sumRange(i,j); + * obj.update(index,val); + * int param_2 = obj.sumRange(left,right); */ diff --git a/Medium/Range Sum Query 2D-Immutable.java b/Medium/Range Sum Query 2D-Immutable.java index 9139dcef..bd30c3e1 100644 --- a/Medium/Range Sum Query 2D-Immutable.java +++ b/Medium/Range Sum Query 2D-Immutable.java @@ -1,21 +1,28 @@ class NumMatrix { - int[][] dp; + + int rows; + int cols; + int[][] rowLevelSum; public NumMatrix(int[][] matrix) { - if (matrix.length == 0 || matrix[0].length == 0) { - return; - } - dp = new int[matrix.length][matrix[0].length + 1]; - for (int i = 0; i < matrix.length; i++) { - for (int j = 0; j < matrix[0].length; j++) { - dp[i][j + 1] = dp[i][j] + matrix[i][j]; + this.rows = matrix.length; + this.cols = matrix[0].length; + this.rowLevelSum = new int[rows][cols]; + for (int i = 0; i < rows; i++) { + int sum = 0; + for (int j = 0; j < cols; j++) { + sum += matrix[i][j]; + this.rowLevelSum[i][j] = sum; } } } public int sumRegion(int row1, int col1, int row2, int col2) { int sum = 0; - for (int row = row1; row <= row2; row++) { - sum += dp[row][col2 + 1] - dp[row][col1]; + for (int i = row1; i <= row2; i++) { + sum += rowLevelSum[i][col2]; + if (col1 > 0) { + sum -= rowLevelSum[i][col1 - 1]; + } } return sum; } diff --git a/Medium/Range Sum of Sorted Subarray Sums.java b/Medium/Range Sum of Sorted Subarray Sums.java index c8dad58b..9b7504b7 100644 --- a/Medium/Range Sum of Sorted Subarray Sums.java +++ b/Medium/Range Sum of Sorted Subarray Sums.java @@ -1,26 +1,23 @@ class Solution { - final int MOD = 100000007; - public int rangeSum(int[] nums, int n, int left, int right) { - PriorityQueue pq = new PriorityQueue<>(new Comparator(){ - public int compare(int[] o1, int[] o2) { - return o1[0] - o2[0]; - } - }); - for (int i = 0; i < n; i++) { - pq.add(new int[]{nums[i], i + 1}); + private static final int MOD = 1000_000_007; + + public int rangeSum(int[] nums, int n, int left, int right) { + Queue pq = new PriorityQueue<>(Comparator.comparingInt(o -> o[0])); + for (int i = 0; i < n; i++) { + pq.add(new int[]{nums[i], i + 1}); + } + int sum = 0; + for (int i = 1; i <= right; i++) { + int[] removed = pq.poll(); + if (i >= left) { + sum = (sum + removed[0]) % MOD; + } + if (removed[1] < n) { + removed[0] = removed[0] + nums[removed[1]]; + removed[1]++; + pq.add(removed); + } + } + return sum; } - int sum = 0; - for (int i = 1; i <= right; i++) { - int[] removed = pq.poll(); - if (i >= left) { - sum = (sum + removed[0]) % MOD; - } - if (removed[1] < n) { - removed[0] = removed[0] + nums[removed[1]]; - removed[1]++; - pq.add(removed); - } - } - return sum; - } } diff --git a/Medium/Rank Teams by Votes.java b/Medium/Rank Teams by Votes.java index f7ced0c6..e3cf32af 100644 --- a/Medium/Rank Teams by Votes.java +++ b/Medium/Rank Teams by Votes.java @@ -1,32 +1,27 @@ class Solution { public String rankTeams(String[] votes) { - Map map = new HashMap<>(); - int n = votes[0].length(); - for(String vote : votes) { - for (int i = 0; i < n; i++) { - if (!map.containsKey(vote.charAt(i))) { - map.put(vote.charAt(i), new int[n]); - } - map.get(vote.charAt(i))[i]++; + Map> map = new HashMap<>(); + int positionCount = votes[0].length(); + for (String vote : votes) { + for (int i = 0; i < vote.length(); i++) { + char c = vote.charAt(i); + map.computeIfAbsent(c, k -> new HashMap<>()); + map.get(c).put(i, map.get(c).getOrDefault(i, 0) + 1); } } - PriorityQueue pq = new PriorityQueue<>(new Comparator(){ - public int compare(Character c1, Character c2) { - for (int i = 0; i < n; i++) { - int c = map.get(c2)[i] - map.get(c1)[i]; - if (c != 0) { - return c; - } + PriorityQueue priorityQueue = new PriorityQueue<>((o1, o2) -> { + for (int i = 0; i < positionCount; i++) { + int c = map.get(o2).getOrDefault(i, 0) - map.get(o1).getOrDefault(i, 0); + if (c != 0) { + return c; } - return c1 - c2; } + return o1 - o2; }); - for (char c : votes[0].toCharArray()) { - pq.add(c); - } + priorityQueue.addAll(map.keySet()); StringBuilder sb = new StringBuilder(); - while (!pq.isEmpty()) { - sb.append(pq.poll()); + while (!priorityQueue.isEmpty()) { + sb.append(priorityQueue.poll()); } return sb.toString(); } diff --git a/Medium/Reachable Nodes With Restrictions.java b/Medium/Reachable Nodes With Restrictions.java new file mode 100644 index 00000000..2a9b6f85 --- /dev/null +++ b/Medium/Reachable Nodes With Restrictions.java @@ -0,0 +1,28 @@ +class Solution { + public int reachableNodes(int n, int[][] edges, int[] restricted) { + Map> graph = new HashMap<>(); + for (int[] edge : edges) { + graph.computeIfAbsent(edge[0], k -> new ArrayList<>()).add(edge[1]); + graph.computeIfAbsent(edge[1], k -> new ArrayList<>()).add(edge[0]); + } + Set restrictedSet = Arrays.stream(restricted).boxed().collect(Collectors.toSet()); + Set visited = new HashSet<>(); + Queue queue = new LinkedList<>(); + queue.add(0); + visited.add(0); + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + int node = queue.remove(); + for (Integer neighbor : graph.getOrDefault(node, new ArrayList<>())) { + if (restrictedSet.contains(neighbor) || visited.contains(neighbor)) { + continue; + } + queue.add(neighbor); + visited.add(neighbor); + } + } + } + return visited.size(); + } +} diff --git a/Medium/Rearrange Array Elements by Sign.java b/Medium/Rearrange Array Elements by Sign.java new file mode 100644 index 00000000..83857f13 --- /dev/null +++ b/Medium/Rearrange Array Elements by Sign.java @@ -0,0 +1,18 @@ +class Solution { + public int[] rearrangeArray(int[] nums) { + int n = nums.length; + int[] result = new int[n]; + int posIndex = 0; + int negIndex = 1; + for (int i = 0; i < n; i++) { + if (nums[i] > 0) { + result[posIndex] = nums[i]; + posIndex += 2; + } else { + result[negIndex] = nums[i]; + negIndex += 2; + } + } + return result; + } +} diff --git a/Medium/Rearrange Array to Maximize Prefix Score.java b/Medium/Rearrange Array to Maximize Prefix Score.java new file mode 100644 index 00000000..6f52eda8 --- /dev/null +++ b/Medium/Rearrange Array to Maximize Prefix Score.java @@ -0,0 +1,15 @@ +class Solution { + public int maxScore(int[] nums) { + Arrays.sort(nums); + long currPrefixSum = 0; + int prefixScore = 0; + for (int i = nums.length - 1; i >= 0; i--) { + currPrefixSum += nums[i]; + if (currPrefixSum <= 0) { + break; + } + prefixScore++; + } + return prefixScore; + } +} diff --git a/Medium/Reconstruct Itinerary.java b/Medium/Reconstruct Itinerary.java deleted file mode 100644 index 7951bfc3..00000000 --- a/Medium/Reconstruct Itinerary.java +++ /dev/null @@ -1,49 +0,0 @@ -class Solution { - List result = null; - public List findItinerary(List> tickets) { - Map> map = new HashMap<>(); - int flights = tickets.size(); - for (List ticket : tickets) { - map.computeIfAbsent(ticket.get(0), k -> new ArrayList<>()).add(ticket.get(1)); - } - Map visited = new HashMap<>(); - for (Map.Entry> entry : map.entrySet()) { - Collections.sort(entry.getValue()); - visited.put(entry.getKey(), new boolean[entry.getValue().size()]); - } - LinkedList route = new LinkedList(); - route.add("JFK"); - backtrack(map, visited, flights, route, "JFK"); - return result; - } - - private boolean backtrack( - Map> map, - Map visited, - int flights, - LinkedList route, - String origin - ) { - if (route.size() == (flights + 1)) { - result = (List) route.clone(); - return true; - } - if (!map.containsKey(origin)) { - return false; - } - boolean[] visit = visited.get(origin); - for (int i = 0; i < map.get(origin).size(); i++) { - if (!visit[i]) { - visit[i] = true; - route.add(map.get(origin).get(i)); - boolean res = backtrack(map, visited, flights, route, map.get(origin).get(i)); - route.pollLast(); - visit[i] = false; - if (res) { - return res; - } - } - } - return false; - } -} diff --git a/Medium/Reconstruct Original Digits from English.java b/Medium/Reconstruct Original Digits from English.java index 77f44e20..606452a6 100644 --- a/Medium/Reconstruct Original Digits from English.java +++ b/Medium/Reconstruct Original Digits from English.java @@ -1,31 +1,30 @@ class Solution { - public String originalDigits(String s) { - int[] count = new int[26]; - for (char c : s.toCharArray()) { - count[c - 'a']++; - } - - int[] out = new int[10]; - - out[0] = count['z' - 'a']; - out[2] = count['w' - 'a']; - out[4] = count['u' - 'a']; - out[6] = count['x' - 'a']; - out[8] = count['g' - 'a']; - out[3] = count['h' - 'a'] - out[8]; - out[5] = count['f' - 'a'] - out[4]; - out[7] = count['s' - 'a'] - out[6]; - out[9] = count['i' - 'a'] - out[5] - out[6] - out[8]; - out[1] = count['n' - 'a'] - out[7] - 2 * out[9]; - - StringBuilder sb = new StringBuilder(); - - for (int i = 0; i < 10; i++) { - for (int j = 0; j < out[i]; j++) { - sb.append(i); - } - } - - return sb.toString(); + public String originalDigits(String s) { + int[] count = new int[10]; + for (int i = 0; i < s.length(); i++){ + char c = s.charAt(i); + if (c == 'z') count[0]++; + if (c == 'w') count[2]++; + if (c == 'x') count[6]++; + if (c == 's') count[7]++; //7-6 + if (c == 'g') count[8]++; + if (c == 'u') count[4]++; + if (c == 'f') count[5]++; //5-4 + if (c == 'h') count[3]++; //3-8 + if (c == 'i') count[9]++; //9-8-5-6 + if (c == 'o') count[1]++; //1-0-2-4 } + count[7] -= count[6]; + count[5] -= count[4]; + count[3] -= count[8]; + count[9] = count[9] - count[8] - count[5] - count[6]; + count[1] = count[1] - count[0] - count[2] - count[4]; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i <= 9; i++){ + for (int j = 0; j < count[i]; j++){ + sb.append(i); + } + } + return sb.toString(); + } } diff --git a/Medium/Recover Binary Search Tree.java b/Medium/Recover Binary Search Tree.java new file mode 100644 index 00000000..8a3a133f --- /dev/null +++ b/Medium/Recover Binary Search Tree.java @@ -0,0 +1,43 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public void recoverTree(TreeNode root) { + TreeNode nodeOne = null; + TreeNode nodeTwo = null; + TreeNode prevNode = null; + Stack stack = new Stack<>(); + while (root != null || !stack.isEmpty()) { + while (root != null) { + stack.push(root); + root = root.left; + } + if (!stack.isEmpty()) { + root = stack.pop(); + if (nodeOne == null && prevNode != null && prevNode.val > root.val) { + nodeOne = prevNode; + } + if (nodeOne != null && prevNode.val > root.val) { + nodeTwo = root; + } + prevNode = root; + root = root.right; + } + } + int tempValue = nodeOne.val; + nodeOne.val = nodeTwo.val; + nodeTwo.val = tempValue; + } +} diff --git a/Medium/Rectangle Overlap.java b/Medium/Rectangle Overlap.java deleted file mode 100644 index 26b038d2..00000000 --- a/Medium/Rectangle Overlap.java +++ /dev/null @@ -1,20 +0,0 @@ -class Solution { - public boolean isRectangleOverlap(int[] rec1, int[] rec2) { - int rec1X1 = rec1[0]; - int rec1X2 = rec1[2]; - int rec1Y1 = rec1[1]; - int rec1Y2 = rec1[3]; - - int rec2X1 = rec2[0]; - int rec2X2 = rec2[2]; - int rec2Y1 = rec2[1]; - int rec2Y2 = rec2[3]; - - return !( - rec1X1 >= rec2X2 || - rec1X2 <= rec2X1 || - rec1Y2 <= rec2Y1 || - rec1Y1 >= rec2Y2 - ); - } -} diff --git a/Medium/Reduce Array Size to The Half.java b/Medium/Reduce Array Size to The Half.java index 50c84326..82572571 100644 --- a/Medium/Reduce Array Size to The Half.java +++ b/Medium/Reduce Array Size to The Half.java @@ -1,24 +1,27 @@ class Solution { public int minSetSize(int[] arr) { Map map = new HashMap<>(); + int maxCount = 0; for (int num : arr) { map.put(num, map.getOrDefault(num, 0) + 1); + maxCount = Math.max(maxCount, map.get(num)); } - PriorityQueue pq = new PriorityQueue<>(new Comparator(){ - public int compare(Integer o1, Integer o2) { - return map.get(o2) - map.get(o1); - } - }); - for (Integer key : map.keySet()) { - pq.add(key); + int[] bucket = new int[maxCount + 1]; + for (int count : map.values()) { + bucket[count]++; } - int n = arr.length / 2; - int currSize = 0; - int count = 0; - while (currSize < n) { - currSize += map.get(pq.poll()); - count++; + int n = arr.length; + int setSize = 0; + int bucketIdx = bucket.length - 1; + while (n > arr.length / 2) { + if (bucket[bucketIdx] > 0) { + setSize++; + n -= bucketIdx; + bucket[bucketIdx]--; + } else { + bucketIdx--; + } } - return count; + return setSize; } } diff --git a/Medium/Reduction Operations to Make the Array Elements Equal.java b/Medium/Reduction Operations to Make the Array Elements Equal.java new file mode 100644 index 00000000..bb55c50e --- /dev/null +++ b/Medium/Reduction Operations to Make the Array Elements Equal.java @@ -0,0 +1,35 @@ +class Solution { + public int reductionOperations(int[] nums) { + Map map = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + map.put(nums[i], map.getOrDefault(nums[i], 0) + 1); + } + PriorityQueue pq = new PriorityQueue<>(new Comparator<>(){ + public int compare(KeyEntry k1, KeyEntry k2) { + return k2.key - k1.key; + } + }); + for (Integer key : map.keySet()) { + pq.add(new KeyEntry(key, map.get(key))); + } + int numOfSteps = 0; + while (pq.size() > 1) { + KeyEntry largest = pq.poll(); + KeyEntry secondLargest = pq.poll(); + secondLargest.val += largest.val; + pq.add(secondLargest); + numOfSteps += largest.val; + } + return numOfSteps; + } +} + +class KeyEntry { + int key; + int val; + + public KeyEntry(int key, int val) { + this.key = key; + this.val = val; + } +} diff --git a/Medium/Remove Adjacent Almost-Equal Characters.java b/Medium/Remove Adjacent Almost-Equal Characters.java new file mode 100644 index 00000000..46bdf2ab --- /dev/null +++ b/Medium/Remove Adjacent Almost-Equal Characters.java @@ -0,0 +1,14 @@ +class Solution { + public int removeAlmostEqualCharacters(String word) { + int count = 0; + for (int i = 0; i < word.length() - 1; i++) { + char curr = word.charAt(i); + char next = word.charAt(i + 1); + if (Math.abs(curr - next) <= 1) { + count++; + i++; + } + } + return count; + } +} diff --git a/Medium/Remove All Adjacent Duplicates in String II.java b/Medium/Remove All Adjacent Duplicates in String II.java index f727a688..0cf6d3ac 100644 --- a/Medium/Remove All Adjacent Duplicates in String II.java +++ b/Medium/Remove All Adjacent Duplicates in String II.java @@ -1,36 +1,33 @@ class Solution { public String removeDuplicates(String s, int k) { - Stack stack = new Stack<>(); + Stack stack = new Stack<>(); for (char c : s.toCharArray()) { - if (!stack.isEmpty() && stack.peek().ch == c) { - stack.peek().val++; + if (!stack.isEmpty() && stack.peek().c == c) { + stack.peek().count++; + } else { + stack.push(new CharPair(c)); } - else { - stack.push(new Pair(c, 1)); - } - if (stack.peek().val == k) { + if (stack.peek().count == k) { stack.pop(); } } StringBuilder sb = new StringBuilder(); while (!stack.isEmpty()) { - Pair removed = stack.pop(); - int count = removed.val; - while (count-- > 0) { - sb.append(removed.ch); + CharPair pair = stack.pop(); + for (int i = 0; i < pair.count; i++) { + sb.append(pair.c); } } return sb.reverse().toString(); } -} - - -class Pair { - char ch; - int val; - public Pair(char ch, int val) { - this.ch = ch; - this.val = val; + private static class CharPair { + char c; + int count; + + public CharPair(char c) { + this.c = c; + this.count = 1; + } } } diff --git a/Medium/Remove All Occurrences of a Substring.java b/Medium/Remove All Occurrences of a Substring.java new file mode 100644 index 00000000..e46ad3f2 --- /dev/null +++ b/Medium/Remove All Occurrences of a Substring.java @@ -0,0 +1,32 @@ +class Solution { + public String removeOccurrences(String s, String part) { + Stack stack = new Stack<>(); + int n = s.length(); + int partLength = part.length(); + for (int i = 0; i < n; i++) { + stack.push(s.charAt(i)); + if (stack.size() >= partLength && check(stack, part, partLength)) { + for (int j = 0; j < partLength; j++) { + stack.pop(); + } + } + } + StringBuilder sb = new StringBuilder(); + while (!stack.isEmpty()) { + sb.append(stack.pop()); + } + return sb.reverse().toString(); + } + + private boolean check(Stack stack, String part, int partLength) { + Stack temp = new Stack<>(); + temp.addAll(stack); + for (int i = partLength - 1; i >= 0; i--) { + if (temp.isEmpty() || temp.peek() != part.charAt(i)) { + return false; + } + temp.pop(); + } + return true; + } +} diff --git a/Medium/Remove All Ones With Row and Column Flips II.java b/Medium/Remove All Ones With Row and Column Flips II.java new file mode 100644 index 00000000..aeeeab2f --- /dev/null +++ b/Medium/Remove All Ones With Row and Column Flips II.java @@ -0,0 +1,23 @@ +class Solution { + public int removeOnes(int[][] grid) { + return removeOnesHelper(grid, 0, 0); + } + + private int removeOnesHelper(int[][] grid, int x, int y) { + int rows = grid.length; + int cols = grid[0].length; + int result = Integer.MAX_VALUE; + int ones = 0; + for (int i = 0; i < rows; i++) { + if ((x & (1 << i)) == 0) { + for (int j = 0; j < cols; j++) { + if ((y & (1 << j)) == 0 && grid[i][j] == 1) { + ones++; + result = Math.min(result, 1 + removeOnesHelper(grid, x + (1 << i), y + (1 << j))); + } + } + } + } + return ones == 0 ? 0 : result; + } +} diff --git a/Medium/Remove Colored Pieces if Both Neighbors are the Same Color.java b/Medium/Remove Colored Pieces if Both Neighbors are the Same Color.java new file mode 100644 index 00000000..950afa6f --- /dev/null +++ b/Medium/Remove Colored Pieces if Both Neighbors are the Same Color.java @@ -0,0 +1,16 @@ +class Solution { + public boolean winnerOfGame(String colors) { + int alice = 0; + int bob = 0; + for (int i = 1; i < colors.length() - 1; i++) { + if (colors.charAt(i - 1) == colors.charAt(i) && colors.charAt(i + 1) == colors.charAt(i)) { + if (colors.charAt(i) == 'A') { + alice++; + } else { + bob++; + } + } + } + return alice - bob > 0; + } +} diff --git a/Medium/Remove Covered Intervals.java b/Medium/Remove Covered Intervals.java index 3adf6ca3..03fdf662 100644 --- a/Medium/Remove Covered Intervals.java +++ b/Medium/Remove Covered Intervals.java @@ -7,18 +7,21 @@ public int removeCoveredIntervals(int[][] intervals) { } return o2[1] - o1[1]; }); - int count = 0; - int idx = 0; + int currIdx = 0; int n = intervals.length; - while (idx < n) { - int start = intervals[idx][0]; - int end = intervals[idx][1]; - idx++; - while (idx < n && intervals[idx][1] <= end) { - idx++; + int intervalCount = 0; + while (currIdx < n) { + int[] currInterval = intervals[currIdx]; + int currIntervalStart = currInterval[0]; + int currIntervalEnd = currInterval[1]; + currIdx++; + while (currIdx < n && + intervals[currIdx][0] >= currIntervalStart && + intervals[currIdx][1] <= currIntervalEnd) { + currIdx++; } - count++; + intervalCount++; } - return count; - } + return intervalCount; + } } diff --git a/Medium/Remove Duplicate Letters.java b/Medium/Remove Duplicate Letters.java new file mode 100644 index 00000000..19bd928d --- /dev/null +++ b/Medium/Remove Duplicate Letters.java @@ -0,0 +1,25 @@ +class Solution { + public String removeDuplicateLetters(String s) { + Map lastIndexMap = new HashMap<>(); + for (int i = 0; i < s.length(); i++) { + lastIndexMap.put(s.charAt(i), i); + } + Stack stack = new Stack<>(); + Set visited = new HashSet<>(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (!visited.contains(c)) { + while (!stack.isEmpty() && c < stack.peek() && lastIndexMap.get(stack.peek()) > i) { + visited.remove(stack.pop()); + } + visited.add(c); + stack.push(c); + } + } + StringBuilder sb = new StringBuilder(); + for (Character c : stack) { + sb.append(c); + } + return sb.toString(); + } +} diff --git a/Medium/Remove Duplicates From Sorted Array II.java b/Medium/Remove Duplicates From Sorted Array II.java index 2ed32e65..63879666 100644 --- a/Medium/Remove Duplicates From Sorted Array II.java +++ b/Medium/Remove Duplicates From Sorted Array II.java @@ -1,29 +1,19 @@ class Solution { - public int removeDuplicates(int[] nums) { - return removeDuplicatesUtil(nums, nums.length, 2); - } - - private int removeDuplicatesUtil(int[] nums, int n, int k) { - if (n <= k) return n; - - int i = 1; - int j = 1; - int cnt = 1; - - while (j < n) { - if (nums[j] != nums[j-1]) { - cnt = 1; - nums[i++] = nums[j]; - } - else { - if (cnt < k) { - nums[i++] = nums[j]; - cnt++; - } - } - ++j; - } - - return i; + public int removeDuplicates(int[] nums) { + int startIdx = 0; + int n = nums.length; + int currIdx = 0; + while (currIdx < n) { + int currValue = nums[currIdx]; + int count = 0; + while (currIdx < n && nums[currIdx] == currValue) { + currIdx++; + count++; + } + for (int i = 0; i < Math.min(2, count); i++) { + nums[startIdx++] = currValue; + } } + return startIdx; + } } diff --git a/Medium/Remove Duplicates From an Unsorted Linked List.java b/Medium/Remove Duplicates From an Unsorted Linked List.java new file mode 100644 index 00000000..18308224 --- /dev/null +++ b/Medium/Remove Duplicates From an Unsorted Linked List.java @@ -0,0 +1,37 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode deleteDuplicatesUnsorted(ListNode head) { + Map map = new HashMap<>(); + ListNode curr = head; + while (curr != null) { + map.put(curr.val, map.getOrDefault(curr.val, 0) + 1); + curr = curr.next; + } + curr = head; + ListNode prev = null; + ListNode newHead = null; + while (curr != null) { + if (map.get(curr.val) > 1) { + if (prev != null) { + prev.next = curr.next; + } + } else { + prev = curr; + if (newHead == null) { + newHead = curr; + } + } + curr = curr.next; + } + return newHead; + } +} diff --git a/Medium/Remove Duplicates from Sorted List II.java b/Medium/Remove Duplicates from Sorted List II.java index 62a3b0e3..edb287cc 100644 --- a/Medium/Remove Duplicates from Sorted List II.java +++ b/Medium/Remove Duplicates from Sorted List II.java @@ -3,27 +3,27 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode deleteDuplicates(ListNode head) { - ListNode curr = head; ListNode prev = null; + ListNode curr = head; while (curr != null) { - if (curr.next != null && curr.val == curr.next.val) { + if (curr.next != null && curr.next.val == curr.val) { int currVal = curr.val; while (curr != null && curr.val == currVal) { curr = curr.next; } if (prev == null) { head = curr; - } - else { + } else { prev.next = curr; } - } - else { + } else { prev = curr; curr = curr.next; } diff --git a/Medium/Remove Interval.java b/Medium/Remove Interval.java index 4ebbcf9e..e64370e0 100644 --- a/Medium/Remove Interval.java +++ b/Medium/Remove Interval.java @@ -1,41 +1,37 @@ class Solution { public List> removeInterval(int[][] intervals, int[] toBeRemoved) { - List> list = new ArrayList<>(); + List> result = new ArrayList<>(); + int n = intervals.length; int removeStart = toBeRemoved[0]; int removeEnd = toBeRemoved[1]; - for (int[] interval : intervals) { - int start = interval[0]; - int end = interval[1]; - // Case 1: Overlap the removal interval. Skip this interval - if (start >= removeStart && end <= removeEnd) { + for (int i = 0; i < n; i++) { + int currStart = intervals[i][0]; + int currEnd = intervals[i][1]; + // complete overlap hence skipping complete interval + if (currStart >= removeStart && currEnd <= removeEnd) { continue; } - // Case 2 and 3: Completely miss out the removal interval either on left side or right side of number line. - // Add the complete interval - if ((start <= removeStart && end <= removeStart) || - (start >= removeEnd && end >= removeEnd)) { - list.add(Arrays.asList(start, end)); + // no overlap hence adding complete interval + if ((currStart <= removeStart && currEnd <= removeStart) || (currStart >= removeEnd && currEnd >= removeEnd)) { + result.add(List.of(currStart, currEnd)); continue; - } - // Case 4: Interval partially overlaps on left side of removal interval on number line. - // Add the modified interval - if (start <= removeStart) { - int tempStart = Math.min(start, removeStart); - int tempEnd = Math.max(start, removeStart); - if (tempStart != tempEnd) { - list.add(Arrays.asList(tempStart, tempEnd)); + } + // partial overlaps + if (currStart <= removeStart) { + int newStart = Math.min(currStart, removeStart); + int newEnd = Math.max(currStart, removeStart); + if (newStart != newEnd) { + result.add(List.of(newStart, newEnd)); } } - // Case 5: Interval partially overlaps on right side of removal interval on number line. - // Add the modified interval - if (end >= removeEnd) { - int tempStart = Math.min(end, removeEnd); - int tempEnd = Math.max(end, removeEnd); - if (tempStart != tempEnd) { - list.add(Arrays.asList(tempStart, tempEnd)); + if (currEnd >= removeEnd) { + int newStart = Math.min(currEnd, removeEnd); + int newEnd = Math.max(currEnd, removeEnd); + if (newStart != newEnd) { + result.add(List.of(newStart, newEnd)); } } } - return list; + return result; } } diff --git a/Medium/Remove Nodes From Linked List.java b/Medium/Remove Nodes From Linked List.java new file mode 100644 index 00000000..850e4da0 --- /dev/null +++ b/Medium/Remove Nodes From Linked List.java @@ -0,0 +1,40 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode removeNodes(ListNode head) { + ListNode revNode = reverse(head); + ListNode curr = revNode; + ListNode prev = null; + int maxValue = Integer.MIN_VALUE; + while (curr != null) { + if (curr.val < maxValue) { + prev.next = curr.next; + } else { + prev = curr; + maxValue = Math.max(curr.val, maxValue); + } + curr = curr.next; + } + return reverse(revNode); + } + + private ListNode reverse(ListNode node) { + ListNode curr = node; + ListNode prev = null; + while (curr != null) { + ListNode next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + return prev; + } +} diff --git a/Medium/Remove Nth Node From End of List.java b/Medium/Remove Nth Node From End of List.java index 44b990bd..f6f741f8 100644 --- a/Medium/Remove Nth Node From End of List.java +++ b/Medium/Remove Nth Node From End of List.java @@ -10,24 +10,19 @@ */ class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { - if (head == null || n == 0) { - return head; + ListNode curr = head; + while (n-- > 0) { + curr = curr.next; } - ListNode slow = head; - int count = 0; - while (count < n) { - slow = slow.next; - count++; - } - if (slow == null) { + if (curr == null) { return head.next; } - ListNode fast = head; - while (slow.next != null) { - slow = slow.next; - fast = fast.next; + ListNode slowNode = head; + while (curr.next != null) { + slowNode = slowNode.next; + curr = curr.next; } - fast.next = fast.next.next; + slowNode.next = slowNode.next.next; return head; } } diff --git a/Medium/Remove Sub-Folders from the Filesystem.java b/Medium/Remove Sub-Folders from the Filesystem.java index 2d91c97e..62f67bcd 100644 --- a/Medium/Remove Sub-Folders from the Filesystem.java +++ b/Medium/Remove Sub-Folders from the Filesystem.java @@ -1,24 +1,67 @@ class Solution { - public List removeSubfolders(String[] folder) { - Set set = new HashSet<>(); - Arrays.sort(folder, new Comparator(){ - public int compare(String s1, String s2) { - return s1.length() - s2.length(); - } - }); - for (String fl : folder) { - String[] files = fl.split("/"); - StringBuilder sb = new StringBuilder(); - for (int i = 1; i < files.length; i++) { - sb.append("/").append(files[i]); - if (set.contains(sb.toString())) { - break; + public List removeSubfolders(String[] folder) { + TrieNode root = new TrieNode(); + for (String file : folder) { + TrieNode curr = root; + String[] splits = file.split("/"); + for (int i = 1; i < splits.length; i++) { + Optional nextNode = curr.getChild(splits[i]); + if (nextNode.isEmpty()) { + TrieNode newNode = curr.addChild(splits[i]); + curr = newNode; + } else { + curr = nextNode.get(); + } + } + curr.markIsFolder(); + } + List result = new ArrayList<>(); + for (String file : folder) { + TrieNode curr = root; + String[] splits = file.split("/"); + boolean isSubfolder = false; + for (int i = 1; i < splits.length; i++) { + TrieNode nextNode = curr.getChild(splits[i]).get(); + if (nextNode.isFolder() && i != splits.length - 1) { + isSubfolder = true; + break; + } + curr = nextNode; + } + if (!isSubfolder) { + result.add(file); + } + } + return result; + } + + class TrieNode { + private boolean isFolder; + private Map children; + + public TrieNode() { + this.children = new HashMap<>(); + } + + public TrieNode addChild(String childKey) { + TrieNode node = new TrieNode(); + children.put(childKey, node); + return node; + } + + public Optional getChild(String childKey) { + if (!children.containsKey(childKey)) { + return Optional.empty(); + } + return Optional.of(children.get(childKey)); + } + + public void markIsFolder() { + isFolder = true; + } + + public boolean isFolder() { + return isFolder; } - } - if (sb.length() > 0) { - set.add(sb.toString()); - } } - return new ArrayList<>(set); - } } diff --git a/Medium/Remove Zero Sum Consecutive Nodes from Linked List.java b/Medium/Remove Zero Sum Consecutive Nodes from Linked List.java index 9807ca95..6f55accd 100644 --- a/Medium/Remove Zero Sum Consecutive Nodes from Linked List.java +++ b/Medium/Remove Zero Sum Consecutive Nodes from Linked List.java @@ -9,25 +9,24 @@ * } */ class Solution { - public ListNode removeZeroSumSublists(ListNode head) { - ListNode dummy = new ListNode(0); - ListNode curr = head; - dummy.next = head; - Map map = new HashMap<>(); - int prefixSum = 0; - map.put(0, dummy); - while (curr != null) { - prefixSum += curr.val; - map.put(prefixSum, curr); - curr = curr.next; + public ListNode removeZeroSumSublists(ListNode head) { + ListNode dummy = new ListNode(0, head); + ListNode curr = dummy; + int prefixSum = 0; + Map map = new HashMap<>(); + map.put(0, curr); + while (curr != null) { + prefixSum += curr.val; + map.put(prefixSum, curr); + curr = curr.next; + } + prefixSum = 0; + curr = dummy; + while (curr != null) { + prefixSum += curr.val; + curr.next = map.get(prefixSum).next; + curr = curr.next; + } + return dummy.next; } - prefixSum = 0; - curr = dummy; - while (curr != null) { - prefixSum += curr.val; - curr.next = map.get(prefixSum).next; - curr = curr.next; - } - return dummy.next; - } } diff --git a/Medium/Removing Stars From a String.java b/Medium/Removing Stars From a String.java new file mode 100644 index 00000000..9278128a --- /dev/null +++ b/Medium/Removing Stars From a String.java @@ -0,0 +1,17 @@ +class Solution { + public String removeStars(String s) { + Stack stack = new Stack<>(); + for (char c : s.toCharArray()) { + if (c == '*') { + stack.pop(); + } else { + stack.push(c); + } + } + StringBuilder sb = new StringBuilder(); + while (!stack.isEmpty()) { + sb.append(stack.pop()); + } + return sb.reverse().toString(); + } +} diff --git a/Medium/Reorder Data in Log Files.java b/Medium/Reorder Data in Log Files.java new file mode 100644 index 00000000..cc14332b --- /dev/null +++ b/Medium/Reorder Data in Log Files.java @@ -0,0 +1,17 @@ +class Solution { + public String[] reorderLogFiles(String[] logs) { + List letterLogs = new ArrayList<>(); + List digitLogs = new ArrayList<>(); + for (String log : logs) { + if (Character.isDigit(log.split("\\s+")[1].charAt(0))) { + digitLogs.add(log); + } else { + letterLogs.add(log); + } + } + letterLogs.sort(Comparator.comparing((String o) -> o.substring(o.indexOf(' ') + 1)) + .thenComparing(o -> o.split("\\s+")[0])); + letterLogs.addAll(digitLogs); + return letterLogs.toArray(new String[0]); + } +} diff --git a/Medium/Reorder List.java b/Medium/Reorder List.java index beb3390b..99b9ea19 100644 --- a/Medium/Reorder List.java +++ b/Medium/Reorder List.java @@ -9,41 +9,35 @@ * } */ class Solution { - public void reorderList(ListNode head) { - if (head == null || head.next == null) { - return; + public void reorderList(ListNode head) { + ListNode slow = head; + ListNode fast = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + } + ListNode secondHalf = reverse(slow.next); + slow.next = null; + ListNode firstHalf = head; + while (firstHalf != null && secondHalf != null) { + ListNode firstNext = firstHalf.next; + ListNode secondNext = secondHalf.next; + firstHalf.next = secondHalf; + secondHalf.next = firstNext; + firstHalf = firstNext; + secondHalf = secondNext; + } } - ListNode fast = head; - ListNode slow = head; - while (fast != null && fast.next != null) { - fast = fast.next.next; - slow = slow.next; + + private ListNode reverse(ListNode node) { + ListNode curr = node; + ListNode prev = null; + while (curr != null) { + ListNode next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + return prev; } - ListNode secondHalf = reverse(slow.next); - slow.next = null; - ListNode firstHalf = head; - ListNode firstNext = null; - ListNode secondNext = null; - while (firstHalf != null && secondHalf != null) { - firstNext = firstHalf.next; - secondNext = secondHalf.next; - firstHalf.next = secondHalf; - secondHalf.next = firstNext; - firstHalf = firstNext; - secondHalf = secondNext; - } - } - - private ListNode reverse(ListNode node) { - ListNode curr = node; - ListNode prev = null; - ListNode next = null; - while (curr != null) { - next = curr.next; - curr.next = prev; - prev = curr; - curr = next; - } - return prev; - } } diff --git a/Medium/Reorder Routes to Make All Paths Lead to the City Zero.java b/Medium/Reorder Routes to Make All Paths Lead to the City Zero.java index 121798de..78f7e54f 100644 --- a/Medium/Reorder Routes to Make All Paths Lead to the City Zero.java +++ b/Medium/Reorder Routes to Make All Paths Lead to the City Zero.java @@ -1,30 +1,31 @@ class Solution { - public int minReorder(int n, int[][] connections) { - Map> map = new HashMap<>(); - Set set = new HashSet<>(); - for (int[] connection : connections) { - map.computeIfAbsent(connection[0], k -> new HashSet<>()).add(connection[1]); - map.computeIfAbsent(connection[1], k -> new HashSet<>()).add(connection[0]); - set.add(connection[0] + "->" + connection[1]); - } - Queue queue = new LinkedList<>(); - queue.add(0); - int numOfReorders = 0; - boolean[] visited = new boolean[n]; - visited[0] = true; - while (!queue.isEmpty()) { - int removed = queue.remove(); - for (int connection : map.getOrDefault(removed, new HashSet<>())) { - if (visited[connection]) { - continue; + public int minReorder(int n, int[][] connections) { + Map>> graph = new HashMap<>(); + for (int[] conn : connections) { + graph.computeIfAbsent(conn[0], k -> new ArrayList<>()).add(List.of(conn[1], 1)); + graph.computeIfAbsent(conn[1], k -> new ArrayList<>()).add(List.of(conn[0], 0)); } - visited[connection] = true; - if (!set.contains(connection + "->" + removed)) { - numOfReorders++; + int[] count = {0}; + bfs(0, n, graph, count); + return count[0]; + } + + private void bfs(int node, int n, Map>> graph, int[] count) { + Queue queue = new LinkedList<>(); + boolean[] visited = new boolean[n]; + visited[node] = true; + queue.add(node); + while (!queue.isEmpty()) { + int removed = queue.remove(); + for (List conn : graph.getOrDefault(removed, new ArrayList<>())) { + int neighbor = conn.get(0); + int direction = conn.get(1); + if (!visited[neighbor]) { + count[0] += direction; + visited[neighbor] = true; + queue.add(neighbor); + } + } } - queue.add(connection); - } } - return numOfReorders; - } } diff --git a/Medium/Reordered Power of 2.java b/Medium/Reordered Power of 2.java new file mode 100644 index 00000000..09c9fe1b --- /dev/null +++ b/Medium/Reordered Power of 2.java @@ -0,0 +1,20 @@ +class Solution { + public boolean reorderedPowerOf2(int n) { + int[] digitCount = count(n); + for (int i = 0; i < 31; i++) { + if (Arrays.equals(digitCount, count(1 << i))) { + return true; + } + } + return false; + } + + private int[] count(int n) { + int[] result = new int[10]; + while (n > 0) { + result[n % 10]++; + n /= 10; + } + return result; + } +} diff --git a/Medium/Reorganize String.java b/Medium/Reorganize String.java index 824bc88b..9dd20760 100644 --- a/Medium/Reorganize String.java +++ b/Medium/Reorganize String.java @@ -1,44 +1,38 @@ class Solution { - public String reorganizeString(String S) { - int buffer = S.length()%2 == 0 ? S.length()/2 : S.length()/2 + 1; + public String reorganizeString(String s) { Map map = new HashMap<>(); - char[] chars = S.toCharArray(); - - for (char c : chars) { + int maxFrequency = 0; + char maxFrequencyLetter = ' '; + int n = s.length(); + for (char c : s.toCharArray()) { map.put(c, map.getOrDefault(c, 0) + 1); - if (map.get(c) > buffer) { - return ""; + if (maxFrequency < map.get(c)) { + maxFrequency = map.get(c); + maxFrequencyLetter = c; } } - - return createString(map); - } - - private String createString(Map map) { - PriorityQueue pq = new PriorityQueue<>((a, b) -> b[1] - a[1]); - for (char c : map.keySet()) { - pq.add(new int[] {c, map.get(c)}); + if (maxFrequency > (n + 1) / 2) { + return ""; } + char[] letters = new char[s.length()]; + int idx = 0; + idx = insertLetter(n, map, maxFrequencyLetter, letters, idx); + map.remove(maxFrequencyLetter); + for (Character key : map.keySet()) { + idx = insertLetter(n, map, key, letters, idx); + } + return String.valueOf(letters); + } - StringBuilder sb = new StringBuilder(); - while (!pq.isEmpty()) { - int[] first = pq.poll(); - if (sb.length() == 0 || first[0] != sb.charAt(sb.length() - 1)) { - sb.append((char) first[0]); - if (--first[1] > 0) { - pq.add(first); - } - } - else { - int[] second = pq.poll(); - sb.append((char) second[0]); - if (--second[1] > 0) { - pq.add(second); - } - pq.add(first); + private static int insertLetter(int n, Map map, char maxFrequencyLetter, char[] letters, int idx) { + while (map.get(maxFrequencyLetter) > 0) { + if (idx >= n) { + idx = 1; } + letters[idx] = maxFrequencyLetter; + idx += 2; + map.put(maxFrequencyLetter, map.get(maxFrequencyLetter) - 1); } - - return sb.toString(); + return idx; } } diff --git a/Medium/Repeated DNA Sequences.java b/Medium/Repeated DNA Sequences.java index ec329cfd..c764a92c 100644 --- a/Medium/Repeated DNA Sequences.java +++ b/Medium/Repeated DNA Sequences.java @@ -1,19 +1,13 @@ class Solution { - public List findRepeatedDnaSequences(String s) { - Map map = new HashMap<>(); - - for (int i=0; i<=s.length() - 10; i++) { - map.put(s.substring(i, i+10), map.getOrDefault(s.substring(i, i+10), 0) + 1); - } - - List ans = new ArrayList<>(); - - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() > 1) { - ans.add(entry.getKey()); - } - } - - return ans; + public List findRepeatedDnaSequences(String s) { + Set seenSequences = new HashSet<>(); + Set duplicateSequences = new HashSet<>(); + for (int idx = 0; idx <= s.length() - 10; idx++) { + String currentSequence = s.substring(idx, idx + 10); + if (!seenSequences.add(currentSequence)) { + duplicateSequences.add(currentSequence); + } } + return new ArrayList<>(duplicateSequences); + } } diff --git a/Medium/Replace Elements in an Array.java b/Medium/Replace Elements in an Array.java new file mode 100644 index 00000000..77140194 --- /dev/null +++ b/Medium/Replace Elements in an Array.java @@ -0,0 +1,14 @@ +class Solution { + public int[] arrayChange(int[] nums, int[][] operations) { + Map indexMap = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + indexMap.put(nums[i], i); + } + for (int[] operation : operations) { + int prevElementIdx = indexMap.get(operation[0]); + indexMap.put(operation[1], prevElementIdx); + nums[prevElementIdx] = operation[1]; + } + return nums; + } +} diff --git a/Medium/Restore the Array From Adjacent Pairs.java b/Medium/Restore the Array From Adjacent Pairs.java new file mode 100644 index 00000000..041f727d --- /dev/null +++ b/Medium/Restore the Array From Adjacent Pairs.java @@ -0,0 +1,31 @@ +class Solution { + public int[] restoreArray(int[][] adjacentPairs) { + int n = adjacentPairs.length + 1; + Map> map = new HashMap<>(); + for (int[] pair : adjacentPairs) { + map.computeIfAbsent(pair[0], k -> new ArrayList<>()).add(pair[1]); + map.computeIfAbsent(pair[1], k -> new ArrayList<>()).add(pair[0]); + } + Queue queue = new LinkedList<>(); + int firstElement = map.entrySet() + .stream() + .filter(entry -> entry.getValue().size() == 1) + .map(Map.Entry::getKey) + .findFirst() + .orElse(-1); + queue.add(firstElement); + Set set = new HashSet<>(); + int[] result = new int[n]; + int idx = 0; + while (!queue.isEmpty()) { + int removed = queue.remove(); + if (set.contains(removed)) { + continue; + } + result[idx++] = removed; + set.add(removed); + queue.addAll(map.get(removed)); + } + return result; + } +} diff --git a/Medium/Resulting String After Adjacent Removals.java b/Medium/Resulting String After Adjacent Removals.java new file mode 100644 index 00000000..efa43bf6 --- /dev/null +++ b/Medium/Resulting String After Adjacent Removals.java @@ -0,0 +1,21 @@ +class Solution { + public String resultingString(String s) { + Stack stack = new Stack<>(); + for (char c : s.toCharArray()) { + if (!stack.isEmpty() && isAdjacent(stack.peek(), c)) { + stack.pop(); + } else { + stack.push(c); + } + } + StringBuilder result = new StringBuilder(); + for (char c : stack) { + result.append(c); + } + return result.toString(); + } + + private static boolean isAdjacent(char first, char second) { + return Math.abs(first - second) == 1 || (first == 'a' && second == 'z') || (first == 'z' && second == 'a'); + } +} diff --git a/Medium/Reverse Integer.java b/Medium/Reverse Integer.java new file mode 100644 index 00000000..6acc2d42 --- /dev/null +++ b/Medium/Reverse Integer.java @@ -0,0 +1,17 @@ +class Solution { + public int reverse(int x) { + int reverse = 0; + while (x != 0) { + int rem = x % 10; + x /= 10; + if (reverse > Integer.MAX_VALUE / 10 || (reverse == Integer.MAX_VALUE / 10 && rem > 7)) { + return 0; + } + if (reverse < Integer.MIN_VALUE / 10 || (reverse == Integer.MIN_VALUE / 10 && rem < -8)) { + return 0; + } + reverse = reverse * 10 + rem; + } + return reverse; + } +} diff --git a/Medium/Reverse Linked List II.java b/Medium/Reverse Linked List II.java index ca17dc02..3835dbcd 100644 --- a/Medium/Reverse Linked List II.java +++ b/Medium/Reverse Linked List II.java @@ -3,37 +3,49 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { - public ListNode reverseBetween(ListNode head, int m, int n) { - if (head == null || m == n || m > n) { - return head; + public ListNode reverseBetween(ListNode head, int left, int right) { + ListNode curr = head; + ListNode prevToLeft = null; + for (int i = 1; i < left; i++) { + prevToLeft = curr; + curr = curr.next; + } + ListNode nextToLeft = prevToLeft == null ? head : prevToLeft.next; + for (int i = left; i < right; i++) { + curr = curr.next; } - - ListNode dummy = new ListNode(0); - dummy.next = head; - ListNode pre = dummy; - ListNode curr = dummy.next; - - for (int i = 1; i < m; i++) { - pre = curr; + ListNode nextToRight = curr.next; + curr.next = null; + if (prevToLeft != null) { + prevToLeft.next = null; + } + ListNode reversedStart = reverse(nextToLeft); + if (prevToLeft != null) { + prevToLeft.next = reversedStart; + } + curr = reversedStart; + while (curr.next != null) { curr = curr.next; } - - ListNode node = pre; - - for (int i = m; i <= n; i++) { - ListNode tmp = curr.next; - curr.next = pre; - pre = curr; - curr = tmp; + curr.next = nextToRight; + return prevToLeft == null ? reversedStart : head; + } + + private ListNode reverse(ListNode head) { + ListNode prev = null; + ListNode curr = head; + while (curr != null) { + ListNode next = curr.next; + curr.next = prev; + prev = curr; + curr = next; } - - node.next.next = curr; - node.next = pre; - - return dummy.next; + return prev; } } diff --git a/Medium/Reverse Nodes in Even Length Groups.java b/Medium/Reverse Nodes in Even Length Groups.java new file mode 100644 index 00000000..5b723f6a --- /dev/null +++ b/Medium/Reverse Nodes in Even Length Groups.java @@ -0,0 +1,57 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode reverseEvenLengthGroups(ListNode head) { + if (head == null) { + return head; + } + int numOfNodes = 1; + ListNode prev = null; + ListNode curr = head; + int totalNumOfNodes = 0; + while (curr != null) { + totalNumOfNodes++; + curr = curr.next; + } + curr = head; + while (curr != null) { + numOfNodes = Math.min(numOfNodes, totalNumOfNodes); + totalNumOfNodes -= numOfNodes; + if (numOfNodes % 2 == 0) { + ListNode[] res = reverseList(curr, numOfNodes); + prev.next = res[0]; + prev = curr; + curr = res[1]; + } else { + for (int i = 0; i < numOfNodes && curr != null; i++) { + prev = curr; + curr = curr.next; + } + } + numOfNodes++; + } + return head; + } + + private ListNode[] reverseList(ListNode node, int n) { + ListNode prev = null; + ListNode curr = node; + ListNode post = null; + while (n-- > 0) { + post = curr.next; + curr.next = prev; + prev = curr; + curr = post; + } + node.next = curr; + return new ListNode[]{prev, post}; + } +} diff --git a/Medium/Reverse Odd Levels of Binary Tree.java b/Medium/Reverse Odd Levels of Binary Tree.java new file mode 100644 index 00000000..72fc142a --- /dev/null +++ b/Medium/Reverse Odd Levels of Binary Tree.java @@ -0,0 +1,55 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public TreeNode reverseOddLevels(TreeNode root) { + int level = 0; + Queue queue = new LinkedList<>(); + queue.add(root); + while (!queue.isEmpty()) { + List currLevel = new ArrayList<>(); + int size = queue.size(); + while (size-- > 0) { + TreeNode removed = queue.remove(); + if (level % 2 != 0) { + currLevel.add(removed); + } + if (removed.left != null) { + queue.add(removed.left); + } + if (removed.right != null) { + queue.add(removed.right); + } + } + if (level % 2 != 0) { + reverseLevel(currLevel); + } + level++; + } + return root; + } + + private void reverseLevel(List currLevel) { + int start = 0; + int end = currLevel.size() - 1; + while (start < end) { + TreeNode startNode = currLevel.get(start++); + TreeNode endNode = currLevel.get(end--); + int temp = startNode.val; + startNode.val = endNode.val; + endNode.val = temp; + } + } +} diff --git a/Medium/Reverse Substrings Between Each Pair of Parentheses.java b/Medium/Reverse Substrings Between Each Pair of Parentheses.java index 082685e4..b2ecb320 100644 --- a/Medium/Reverse Substrings Between Each Pair of Parentheses.java +++ b/Medium/Reverse Substrings Between Each Pair of Parentheses.java @@ -1,17 +1,29 @@ class Solution { - public String reverseParentheses(String s) { - int start = 0; - int end = 0; - for (int i = 0; i < s.length(); i++) { - if (s.charAt(i) == '(') { - start = i; - } - if (s.charAt(i) == ')') { - end = i; - StringBuilder sb = new StringBuilder(s.substring(start + 1, end)).reverse(); - return reverseParentheses(s.substring(0, start) + sb.toString() + s.substring(end + 1)); - } - } - return s; + public String reverseParentheses(String s) { + char[] letters = s.toCharArray(); + Stack stack = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '(') { + stack.push(i); + } else if (s.charAt(i) == ')') { + reverse(letters, stack.pop(), i); + } } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < letters.length; i++) { + if (letters[i] == '(' || letters[i] == ')') { + continue; + } + sb.append(letters[i]); + } + return sb.toString(); + } + + private void reverse(char[] letters, int start, int end) { + while (start < end) { + char temp = letters[start]; + letters[start++] = letters[end]; + letters[end--] = temp; + } + } } diff --git a/Medium/Reverse Words in a String II.java b/Medium/Reverse Words in a String II.java index 1931ba7d..c3ce706c 100644 --- a/Medium/Reverse Words in a String II.java +++ b/Medium/Reverse Words in a String II.java @@ -1,27 +1,22 @@ class Solution { - public static void reverseWords(char[] str) { - reverse(str, 0, str.length); - - int start = 0; - for (int i=0; i stack = new Stack<>(); - StringBuilder sb = new StringBuilder(); - int idx = 0; - int n = s.length(); - while (idx < n) { - if (s.charAt(idx) != ' ') { - sb.append(s.charAt(idx)); - } - if (s.charAt(idx) == ' ' || idx == n - 1) { - if (sb.length() > 0) { - stack.push(sb.toString()); - sb.setLength(0); + public String reverseWords(String s) { + StringBuilder result = new StringBuilder(); + int idx = s.length() - 1; + while (idx >= 0) { + if (s.charAt(idx) == ' ') { + idx--; + continue; + } + StringBuilder sb = new StringBuilder(); + while (idx >= 0 && Character.isLetterOrDigit(s.charAt(idx))) { + sb.append(s.charAt(idx--)); + } + result.append(sb.reverse().toString()).append(" "); } - } - idx++; + return result.toString().trim(); } - sb.setLength(0); - while (!stack.isEmpty()) { - sb.append(stack.pop()); - if (!stack.isEmpty()) { - sb.append(" "); - } - } - return sb.toString(); - } } diff --git a/Medium/Right Triangles.java b/Medium/Right Triangles.java new file mode 100644 index 00000000..d94804b3 --- /dev/null +++ b/Medium/Right Triangles.java @@ -0,0 +1,25 @@ +class Solution { + public long numberOfRightTriangles(int[][] grid) { + int rows = grid.length; + int cols = grid[0].length; + int[] rowCount = new int[rows]; + int[] colCount = new int[cols]; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (grid[i][j] == 1) { + rowCount[i]++; + colCount[j]++; + } + } + } + long triangles = 0; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + if (grid[i][j] == 1) { + triangles += (rowCount[i] - 1) * (colCount[j] - 1); + } + } + } + return triangles; + } +} diff --git a/Medium/Rotate Array.java b/Medium/Rotate Array.java new file mode 100644 index 00000000..1090cd86 --- /dev/null +++ b/Medium/Rotate Array.java @@ -0,0 +1,19 @@ +class Solution { + public void rotate(int[] nums, int k) { + int n = nums.length; + k %= n; + int count = 0; + for (int i = 0; count < n; i++) { + int currIdx = i; + int prevValue = nums[i]; + do { + int nextIdx = (currIdx + k) % n; + int tempValue = nums[nextIdx]; + nums[nextIdx] = prevValue; + prevValue = tempValue; + currIdx = nextIdx; + count++; + } while (i != currIdx); + } + } +} diff --git a/Medium/Rotate List.java b/Medium/Rotate List.java index a761b879..ddcbd094 100644 --- a/Medium/Rotate List.java +++ b/Medium/Rotate List.java @@ -13,17 +13,17 @@ public ListNode rotateRight(ListNode head, int k) { if (head == null || k == 0) { return head; } - int listSize = 0; + int n = 0; ListNode curr = head; while (curr != null) { + n++; curr = curr.next; - listSize++; } - k = k % listSize; + k = k % n; if (k == 0) { return head; } - k = listSize - k; + k = n - k; curr = head; while (k-- > 1) { curr = curr.next; diff --git a/Medium/Rotated Digits.java b/Medium/Rotated Digits.java new file mode 100644 index 00000000..5d0104e8 --- /dev/null +++ b/Medium/Rotated Digits.java @@ -0,0 +1,25 @@ +class Solution { + public int rotatedDigits(int n) { + int[] dp = new int[n + 1]; + int result = 0; + for (int i = 0; i <= Math.min(n, 9); i++) { + if (i == 0 || i == 1 || i == 8) { + dp[i] = 1; + } else if (i == 2 || i == 5 || i == 6 || i == 9) { + dp[i] = 2; + result++; + } + } + for (int i = 10; i <= n; i++) { + int factor = dp[i / 10]; + int remainder = dp[i % 10]; + if (factor == 1 && remainder == 1) { + dp[i] = 1; + } else if (factor >= 1 && remainder >= 1) { + dp[i] = 2; + result++; + } + } + return result; + } +} diff --git a/Medium/Rotting Oranges.java b/Medium/Rotting Oranges.java index a4eb051f..dd9a1be5 100644 --- a/Medium/Rotting Oranges.java +++ b/Medium/Rotting Oranges.java @@ -1,39 +1,37 @@ class Solution { - int[][] dirs = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; - public final int VISITED = -1; + private final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + public int orangesRotting(int[][] grid) { - int minutes = 0; Queue queue = new LinkedList<>(); - for (int i = 0; i < grid.length; i++) { - for (int j = 0; j < grid[i].length; j++) { + int nonRottenCount = 0; + int numRows = grid.length; + int numCols = grid[0].length; + for (int i = 0; i < numRows; i++) { + for (int j = 0; j < numCols; j++) { if (grid[i][j] == 2) { queue.add(new int[]{i, j}); + } else if (grid[i][j] == 1) { + nonRottenCount++; } } } - while (!queue.isEmpty()) { + int totalTime = 0; + while (!queue.isEmpty() && nonRottenCount > 0) { int size = queue.size(); while (size-- > 0) { int[] removed = queue.remove(); - for (int[] dir : dirs) { + for (int[] dir : DIRS) { int newX = removed[0] + dir[0]; int newY = removed[1] + dir[1]; - if (newX >= 0 && newX < grid.length && newY >= 0 && newY < grid[0].length && grid[newX][newY] == 1) { + if (newX >= 0 && newY >= 0 && newX < numRows && newY < numCols && grid[newX][newY] == 1) { grid[newX][newY] = 2; + nonRottenCount--; queue.add(new int[]{newX, newY}); } } - grid[removed[0]][removed[1]] = VISITED; } - minutes++; + totalTime++; } - for (int i = 0; i < grid.length; i++) { - for (int j = 0; j < grid[i].length; j++) { - if (grid[i][j] == 1) { - return -1; - } - } - } - return minutes > 0 ? minutes - 1 : 0; + return nonRottenCount == 0 ? totalTime : -1; } } diff --git a/Medium/Satisfiability of Equality Equations.java b/Medium/Satisfiability of Equality Equations.java new file mode 100644 index 00000000..cba2bf2a --- /dev/null +++ b/Medium/Satisfiability of Equality Equations.java @@ -0,0 +1,42 @@ +class Solution { + public boolean equationsPossible(String[] equations) { + List[] graph = new ArrayList[26]; + for (int i = 0; i < 26; i++) { + graph[i] = new ArrayList<>(); + } + for (String equation : equations) { + if (equation.charAt(1) == '=') { + int first = equation.charAt(0) - 'a'; + int second = equation.charAt(3) - 'a'; + graph[first].add(second); + graph[second].add(first); + } + } + int[] color = new int[26]; + Arrays.fill(color, -1); + for (int i = 0; i < 26; i++) { + if (color[i] == -1) { + dfs(i, i, color, graph); + } + } + for (String equation : equations) { + if (equation.charAt(1) == '!') { + int first = equation.charAt(0) - 'a'; + int second = equation.charAt(3) - 'a'; + if (color[first] == color[second]) { + return false; + } + } + } + return true; + } + + private static void dfs(int node, int nodeColor, int[] color, List[] graph) { + if (color[node] == -1) { + color[node] = nodeColor; + for (int neighbor : graph[node]) { + dfs(neighbor, nodeColor, color, graph); + } + } + } +} diff --git a/Medium/Score After Flipping Matrix.java b/Medium/Score After Flipping Matrix.java index c369309d..54c3f3ac 100644 --- a/Medium/Score After Flipping Matrix.java +++ b/Medium/Score After Flipping Matrix.java @@ -1,59 +1,33 @@ class Solution { - public int matrixScore(int[][] A) { - for (int i=0; i actualSum) { - for (int j=0; j numOnes) { - for (int j=0; j rows-countZero) { + for(int i = 0; i < rows; i++) { + grid[i][j] = 1 - grid[i][j]; } } } - - int maxSum = 0; - for (int[] arr : A) { - maxSum += getDecimalValue(arr, false); - } - - return maxSum; - } - - private int getDecimalValue(int[] arr, boolean isToggled) { - int sum = 0; - int pow = 0; - - for (int i=arr.length-1; i>=0; i--) { - if (isToggled) { - sum += Math.pow(2, pow) * (arr[i] ^ 1); - } - else { - sum += Math.pow(2, pow) * arr[i]; + int score = 0; + for (int[] row : grid) { + for (int j = 0; j < cols; j++) { + score += row[j] << (cols - j - 1); } - - pow++; } - - return sum; + return score; } } diff --git a/Medium/Score of Parentheses.java b/Medium/Score of Parentheses.java index 0366b58d..43851423 100644 --- a/Medium/Score of Parentheses.java +++ b/Medium/Score of Parentheses.java @@ -1,25 +1,15 @@ class Solution { - public static int scoreOfParentheses(String S) { - Stack st = new Stack<>(); - for (int i=0; i stack = new Stack<>(); + int currMultiplier = 0; + for (char c : S.toCharArray()) { + if (c == '(') { + stack.push(currMultiplier); + currMultiplier = 0; + } else { + currMultiplier = stack.pop() + Math.max(2 * currMultiplier, 1); + } } + return currMultiplier; + } } diff --git a/Medium/Search Suggestions System.java b/Medium/Search Suggestions System.java index 465bde7f..47458964 100644 --- a/Medium/Search Suggestions System.java +++ b/Medium/Search Suggestions System.java @@ -1,59 +1,46 @@ class Solution { public List> suggestedProducts(String[] products, String searchWord) { - Node root = new Node('-'); - for (String product : products) { - addProduct(product, root); + TrieNode root = new TrieNode(); + for (String prod : products) { + TrieNode curr = root; + for (char c : prod.toCharArray()) { + if (curr.children[c - 'a'] == null) { + curr.children[c - 'a'] = new TrieNode(); + } + curr = curr.children[c - 'a']; + curr.matchingProducts.add(prod); + } } - List> list = new ArrayList<>(); - Node curr = root; - boolean notFound = false; + List> result = new ArrayList<>(); + TrieNode curr = root; for (char c : searchWord.toCharArray()) { - if (notFound) { - list.add(new ArrayList<>()); - } - else { - if (!curr.children.containsKey(c)) { - notFound = true; - list.add(new ArrayList<>()); - continue; + if (curr == null) { + result.add(new ArrayList<>()); + } else { + if (curr.children[c - 'a'] == null) { + curr = null; + result.add(new ArrayList<>()); + } else { + curr = curr.children[c - 'a']; + PriorityQueue currMatchingProductsQueue = new PriorityQueue<>(curr.matchingProducts); + List currMatchingProducts = new ArrayList<>(); + while (!currMatchingProductsQueue.isEmpty() && currMatchingProducts.size() < 3) { + currMatchingProducts.add(currMatchingProductsQueue.poll()); + } + result.add(currMatchingProducts); } - curr = curr.children.get(c); - List temp = new ArrayList<>(); - PriorityQueue words = new PriorityQueue<>(curr.possibleWords); - for (int i = 0; i < 3 && !words.isEmpty(); i++) { - temp.add(words.poll()); - } - Collections.reverse(temp); - list.add(temp); } } - return list; + return result; } - private void addProduct(String product, Node root) { - Node curr = root; - for (int i = 0; i < product.length(); i++) { - if (!curr.children.containsKey(product.charAt(i))) { - curr.children.put(product.charAt(i), new Node(product.charAt(i))); - } - curr = curr.children.get(product.charAt(i)); - curr.possibleWords.add(product); - if (curr.possibleWords.size() > 3) { - curr.possibleWords.poll(); - } + private class TrieNode { + TrieNode[] children; + PriorityQueue matchingProducts; + + public TrieNode() { + this.children = new TrieNode[26]; + this.matchingProducts = new PriorityQueue<>(); } } } - - -class Node { - char c; - Map children; - PriorityQueue possibleWords; - - public Node(char c) { - this.c = c; - children = new HashMap<>(); - possibleWords = new PriorityQueue<>(Comparator.reverseOrder()); - } -} diff --git a/Medium/Search a 2D Matrix II.java b/Medium/Search a 2D Matrix II.java new file mode 100644 index 00000000..c409ef25 --- /dev/null +++ b/Medium/Search a 2D Matrix II.java @@ -0,0 +1,18 @@ +class Solution { + public boolean searchMatrix(int[][] matrix, int target) { + int rows = matrix.length; + int cols = matrix[0].length; + int rowIdx = rows - 1; + int colIdx = 0; + while (rowIdx >= 0 && colIdx < cols) { + if (matrix[rowIdx][colIdx] > target) { + rowIdx--; + } else if (matrix[rowIdx][colIdx] < target) { + colIdx++; + } else { + return true; + } + } + return false; + } +} diff --git a/Medium/Search a 2D Matrix.java b/Medium/Search a 2D Matrix.java index 18236db6..086454e0 100644 --- a/Medium/Search a 2D Matrix.java +++ b/Medium/Search a 2D Matrix.java @@ -1,26 +1,21 @@ class Solution { - public boolean searchMatrix(int[][] matrix, int target) { - if (matrix.length == 0 || matrix[0].length == 0) { - return false; - } - int i = 0; - int j = 0; - int rows = matrix.length; - int cols = matrix[0].length; - while (i < rows && j < cols) { - int num = matrix[i][j]; - if (num == target) { - return true; - } - else { - if (i != rows - 1 && matrix[i + 1][j] <= target) { - i++; - } - else { - j++; + public boolean searchMatrix(int[][] matrix, int target) { + int row = matrix.length - 1; + int col = matrix[0].length - 1; + while (row >= 0 && col >= 0) { + if (matrix[row][col] == target) { + return true; + } + if (matrix[row][col] > target) { + col--; + if (col < 0) { + col = matrix[0].length - 1; + row--; + } + } else { + row--; + } } - } + return false; } - return false; - } } diff --git a/Medium/Search in Rotated Sorted Array II.java b/Medium/Search in Rotated Sorted Array II.java index 83c15734..bcb34f99 100644 --- a/Medium/Search in Rotated Sorted Array II.java +++ b/Medium/Search in Rotated Sorted Array II.java @@ -1,35 +1,28 @@ class Solution { - public boolean search(int[] nums, int target) { - int start = 0; - int end = nums.length - 1; - int mid = -1; - while (start <= end) { - mid = (start + end) / 2; - if (nums[mid] == target) { - return true; - } - // Either right side is sorted or left side is unsorted - if (nums[mid] < nums[end] || nums[mid] < nums[start]) { - if (target > nums[mid] && target <= nums[end]) { - start = mid + 1; + public boolean search(int[] nums, int target) { + int start = 0; + int end = nums.length - 1; + while (start <= end) { + int mid = (start + end) / 2; + if (nums[mid] == target) { + return true; + } + if (nums[mid] < nums[end] || nums[mid] < nums[start]) { + if (target > nums[mid] && target <= nums[end]) { + start = mid + 1; + } else { + end = mid - 1; + } + } else if (nums[mid] > nums[start] || nums[mid] > nums[end]) { + if (target < nums[mid] && target >= nums[start]) { + end = mid - 1; + } else { + start = mid + 1; + } + } else { + end--; + } } - else { - end = mid - 1; - } - } - // Either left side is sorted or right side is unsorted - else if (nums[mid] > nums[start] || nums[mid] > nums[end]) { - if (target < nums[mid] && target >= nums[start]) { - end = mid - 1; - } - else { - start = mid + 1; - } - } - else { - end--; - } + return false; } - return false; - } } diff --git a/Medium/Seat Reservation Manager.java b/Medium/Seat Reservation Manager.java new file mode 100644 index 00000000..8a7e8edb --- /dev/null +++ b/Medium/Seat Reservation Manager.java @@ -0,0 +1,26 @@ +class SeatManager { + + private PriorityQueue seats; + + public SeatManager(int n) { + this.seats = new PriorityQueue<>(); + for (int i = 1; i <= n; i++) { + this.seats.add(i); + } + } + + public int reserve() { + return this.seats.poll(); + } + + public void unreserve(int seatNumber) { + this.seats.add(seatNumber); + } +} + +/** + * Your SeatManager object will be instantiated and called as such: + * SeatManager obj = new SeatManager(n); + * int param_1 = obj.reserve(); + * obj.unreserve(seatNumber); + */ diff --git a/Medium/Sender With Largest Word Count.java b/Medium/Sender With Largest Word Count.java new file mode 100644 index 00000000..6bb1bf25 --- /dev/null +++ b/Medium/Sender With Largest Word Count.java @@ -0,0 +1,22 @@ +import java.util.Map.Entry; + + +class Solution { + public String largestWordCount(String[] messages, String[] senders) { + Map map = new HashMap<>(); + for (int i = 0; i < messages.length; i++) { + int wordCount = messages[i].split("\\s+").length; + map.put(senders[i], map.getOrDefault(senders[i], 0) + wordCount); + } + return map.entrySet().stream() + .sorted((o1, o2) -> { + int c = o2.getValue() - o1.getValue(); + if (c != 0) { + return c; + } + return o2.getKey().compareTo(o1.getKey());}) + .map(Entry::getKey) + .findFirst() + .orElse(""); + } +} diff --git a/Medium/Sentence Similarity III.java b/Medium/Sentence Similarity III.java new file mode 100644 index 00000000..506dc110 --- /dev/null +++ b/Medium/Sentence Similarity III.java @@ -0,0 +1,26 @@ +class Solution { + public boolean areSentencesSimilar(String sentence1, String sentence2) { + int idxOneStart = 0; + int idxTwoStart = 0; + String[] wordsOne = sentence1.split("\\s+"); + String[] wordsTwo = sentence2.split("\\s+"); + while (idxOneStart < wordsOne.length && idxOneStart < wordsTwo.length && wordsOne[idxOneStart].equals(wordsTwo[idxTwoStart])) { + idxOneStart++; + idxTwoStart++; + } + boolean startFound = idxOneStart > 0; + if (idxOneStart == wordsOne.length && idxTwoStart == wordsTwo.length) { + return true; + } + int idxOneEnd = wordsOne.length - 1; + int idxTwoEnd = wordsTwo.length - 1; + while (idxOneEnd >= idxOneStart && idxTwoEnd >= idxTwoStart && wordsOne[idxOneEnd].equals(wordsTwo[idxTwoEnd])) { + idxOneEnd--; + idxTwoEnd--; + } + if (idxOneEnd != idxOneStart - 1 && idxTwoEnd != idxTwoStart - 1) { + return false; + } + return true; + } +} diff --git a/Medium/Separate Black and White Balls.java b/Medium/Separate Black and White Balls.java new file mode 100644 index 00000000..5fc4900f --- /dev/null +++ b/Medium/Separate Black and White Balls.java @@ -0,0 +1,13 @@ +class Solution { + public long minimumSteps(String s) { + int whitePos = 0; + long swaps = 0; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '0') { + swaps += i - whitePos; + whitePos++; + } + } + return swaps; + } +} diff --git a/Medium/Sequential Digits.java b/Medium/Sequential Digits.java index ab52770d..94cc1b23 100644 --- a/Medium/Sequential Digits.java +++ b/Medium/Sequential Digits.java @@ -2,17 +2,17 @@ class Solution { public List sequentialDigits(int low, int high) { String bucket = "123456789"; int n = 10; - List list = new ArrayList<>(); - int lowLength = String.valueOf(low).length(); - int highLength = String.valueOf(high).length(); - for (int length = lowLength; length < highLength + 1; length++) { - for (int start = 0; start < n - length; start++) { - int num = Integer.parseInt(bucket.substring(start, start + length)); + List result = new ArrayList<>(); + int minLength = String.valueOf(low).length(); + int maxLength = String.valueOf(high).length(); + for (int currLength = minLength; currLength <= maxLength; currLength++) { + for (int idx = 0; idx < n - currLength; idx++) { + int num = Integer.parseInt(bucket.substring(idx, idx + currLength)); if (num >= low && num <= high) { - list.add(num); + result.add(num); } } } - return list; + return result; } } diff --git a/Medium/Serialize and Deserialize BST.java b/Medium/Serialize and Deserialize BST.java index 7f740386..a6da4bff 100644 --- a/Medium/Serialize and Deserialize BST.java +++ b/Medium/Serialize and Deserialize BST.java @@ -10,51 +10,49 @@ public class Codec { // Encodes a tree to a single string. - public StringBuilder sb; public String serialize(TreeNode root) { if (root == null) { return "#"; } - - sb = new StringBuilder(); - serializeHelper(root); - return sb.toString(); + StringBuilder sb = new StringBuilder(); + dfsSerialize(root, sb); + return sb.toString().trim(); } - - private void serializeHelper(TreeNode root) { + + private void dfsSerialize(TreeNode root, StringBuilder sb) { if (root == null) { - sb.append('#').append(','); + sb.append("#").append(" "); return; } - - sb.append(root.val).append(','); - serializeHelper(root.left); - serializeHelper(root.right); + sb.append(root.val).append(" "); + dfsSerialize(root.left, sb); + dfsSerialize(root.right, sb); } // Decodes your encoded data to tree. public TreeNode deserialize(String data) { - Queue q = new LinkedList<>(Arrays.asList(data.split(","))); - return deserializeHelper(q); + Queue queue = new LinkedList<>(Arrays.asList(data.split("\\s+"))); + return dfsDeserialize(queue); } - - private TreeNode deserializeHelper(Queue queue) { + + private TreeNode dfsDeserialize(Queue queue) { if (queue.isEmpty()) { return null; } - String s = queue.remove(); - if (s.equals("#")) { + String removed = queue.remove(); + if (removed.equals("#")) { return null; } - - TreeNode root = new TreeNode(Integer.parseInt(s)); - root.left = deserializeHelper(queue); - root.right = deserializeHelper(queue); - + TreeNode root = new TreeNode(Integer.parseInt(removed)); + root.left = dfsDeserialize(queue); + root.right = dfsDeserialize(queue); return root; } } // Your Codec object will be instantiated and called as such: -// Codec codec = new Codec(); -// codec.deserialize(codec.serialize(root)); +// Codec ser = new Codec(); +// Codec deser = new Codec(); +// String tree = ser.serialize(root); +// TreeNode ans = deser.deserialize(tree); +// return ans; diff --git a/Medium/Set Matrix Zeroes.java b/Medium/Set Matrix Zeroes.java index 5aad58c2..d2a2e67a 100644 --- a/Medium/Set Matrix Zeroes.java +++ b/Medium/Set Matrix Zeroes.java @@ -1,55 +1,50 @@ class Solution { public void setZeroes(int[][] matrix) { + int rows = matrix.length; + int cols = matrix[0].length; boolean firstRowZero = false; boolean firstColZero = false; - int numRows = matrix.length; - int numCols = matrix[0].length; - // Mark if first column needs to be set zero - for (int i = 0; i < numRows; i++) { + for (int i = 0; i < rows; i++) { if (matrix[i][0] == 0) { firstColZero = true; + break; } } - // Mark if first row needs to be set zero - for (int i = 0; i < numCols; i++) { + for (int i = 0; i < cols; i++) { if (matrix[0][i] == 0) { firstRowZero = true; + break; } } - // If a value in matrix is zero set the value at first row and column to be zero - for (int i = 1; i < numRows; i++) { - for (int j = 1; j < numCols; j++) { + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { if (matrix[i][j] == 0) { matrix[0][j] = 0; matrix[i][0] = 0; } } } - // Update the complete column to be zero if first item of row is zero - for (int i = 1; i < numRows; i++) { + for (int i = 1; i < rows; i++) { if (matrix[i][0] == 0) { - for (int j = 1; j < numCols; j++) { + for (int j = 0; j < cols; j++) { matrix[i][j] = 0; } } } - // Update the complete row to be zero if first item of column is zero - for (int i = 1; i < numCols; i++) { + for (int i = 1; i < cols; i++) { if (matrix[0][i] == 0) { - for (int j = 1; j < numRows; j++) { + for (int j = 0; j < rows; j++) { matrix[j][i] = 0; } - } + } } - // Set the first row to zero if flag is set if (firstRowZero) { - for (int i = 0; i < numCols; i++) { + for (int i = 0; i < cols; i++) { matrix[0][i] = 0; } } - // Set the first column to zero if flag is set if (firstColZero) { - for (int i = 0; i < numRows; i++) { + for (int i = 0; i < rows; i++) { matrix[i][0] = 0; } } diff --git a/Medium/Shifting Letters.java b/Medium/Shifting Letters.java index ccdaa3b4..7d1e7c18 100644 --- a/Medium/Shifting Letters.java +++ b/Medium/Shifting Letters.java @@ -1,40 +1,16 @@ class Solution { - public String shiftingLetters(String S, int[] shifts) { - long[] numOfShifts = getNumOfShifts(shifts); - String shiftedString = getShiftedString(S, numOfShifts); - - return shiftedString; - } - - private long[] getNumOfShifts(int[] shifts) { - long totalShifts = 0; - long[] cumulativeSum = new long[shifts.length]; - for (int i=0; i 0 ? cumulativeSum[i-1] : 0)) % 26; - } - - return numOfShifts; - } - - private String getShiftedString(String s, long[] numOfShifts) { - StringBuilder sb = new StringBuilder(); - - for (int i=0; i 122) { - shiftedValue = 96 + (shiftedValue - 122); - } - - sb.append((char) shiftedValue); - } - - return sb.toString(); + public String shiftingLetters(String s, int[] shifts) { + long totalShifts = 0; + StringBuilder sb = new StringBuilder(); + for (int i = shifts.length - 1; i >= 0; i--) { + totalShifts += shifts[i]; + sb.append(getShiftedChar(s.charAt(i), totalShifts)); } + return sb.reverse().toString(); + } + + private char getShiftedChar(char c, long shifts) { + long newAscii = ((int) c) + (shifts % 26); + return (char) (newAscii > 122 ? (97 + (newAscii - 122) - 1) : newAscii); + } } diff --git a/Medium/Short Encoding of Words.java b/Medium/Short Encoding of Words.java new file mode 100644 index 00000000..6eccb589 --- /dev/null +++ b/Medium/Short Encoding of Words.java @@ -0,0 +1,34 @@ +class Solution { + public int minimumLengthEncoding(String[] words) { + TrieNode root = new TrieNode(); + Map nodes = new HashMap<>(); + for (int i = 0; i < words.length; i++) { + TrieNode curr = root; + for (int j = words[i].length() - 1; j >= 0; j--) { + if (curr.children[words[i].charAt(j) - 'a'] == null) { + curr.children[words[i].charAt(j) - 'a'] = new TrieNode(); + curr.count++; + } + curr = curr.children[words[i].charAt(j) - 'a']; + } + nodes.put(curr, i); + } + int result = 0; + for (TrieNode node : nodes.keySet()) { + if (node.count == 0) { + result += words[nodes.get(node)].length() + 1; + } + } + return result; + } + + private class TrieNode { + TrieNode[] children; + int count; + + public TrieNode() { + this.children = new TrieNode[26]; + this.count = 0; + } + } +} diff --git a/Medium/Shortest Bridge.java b/Medium/Shortest Bridge.java new file mode 100644 index 00000000..f5194373 --- /dev/null +++ b/Medium/Shortest Bridge.java @@ -0,0 +1,65 @@ +class Solution { + + private static final int[][] DIRS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; + + public int shortestBridge(int[][] grid) { + int n = grid.length; + int x = -1; + int y = -1; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 1) { + x = i; + y = j; + break; + } + } + } + List queueOne = new ArrayList<>(); + List queueTwo = new ArrayList<>(); + queueOne.add(new int[]{x, y}); + queueTwo.add(new int[]{x, y}); + grid[x][y] = 2; + while (!queueOne.isEmpty()) { + List bfs = new ArrayList<>(); + for (int[] cell : queueOne) { + int currX = cell[0]; + int currY = cell[1]; + for (int[] dir : DIRS) { + int newX = currX + dir[0]; + int newY = currY + dir[1]; + if (newX >= 0 && newX < n && newY >= 0 && newY < n && grid[newX][newY] == 1) { + bfs.add(new int[]{newX, newY}); + queueTwo.add(new int[]{newX, newY}); + grid[newX][newY] = 2; + } + } + } + queueOne = bfs; + } + int distance = 0; + while (!queueTwo.isEmpty()) { + List bfs = new ArrayList<>(); + for (int[] cell : queueTwo) { + int currX = cell[0]; + int currY = cell[1]; + for (int[] dir : DIRS) { + int newX = currX + dir[0]; + int newY = currY + dir[1]; + if (newX >= 0 && newX < n && newY >= 0 && newY < n) { + if (grid[newX][newY] == 1) { + return distance; + } else if (grid[newX][newY] == 0) { + bfs.add(new int[]{newX, newY}); + grid[newX][newY] = -1; + } + } + } + } + queueTwo = bfs; + distance++; + } + return distance; + } +} + diff --git a/Medium/Shortest Distance After Road Addition Queries I.java b/Medium/Shortest Distance After Road Addition Queries I.java new file mode 100644 index 00000000..19a2ea74 --- /dev/null +++ b/Medium/Shortest Distance After Road Addition Queries I.java @@ -0,0 +1,39 @@ +class Solution { + public int[] shortestDistanceAfterQueries(int n, int[][] queries) { + Map> graph = new HashMap<>(); + for (int i = 0; i < n - 1; i++) { + graph.computeIfAbsent(i, k -> new HashSet<>()).add(i + 1); + } + int[] result = new int[queries.length]; + for (int i = 0; i < queries.length; i++) { + int[] query = queries[i]; + graph.computeIfAbsent(query[0], k -> new HashSet<>()).add(query[1]); + result[i] = findDistance(graph, n - 1); + } + return result; + } + + private int findDistance(Map> graph, int target) { + Queue queue = new LinkedList<>(); + Set visited = new HashSet<>(); + queue.add(0); + int distance = 0; + while (!queue.isEmpty()) { + int size = queue.size(); + for (int i = 0; i < size; i++) { + Integer node = queue.poll(); + if (node == target) { + return distance; + } + for (Integer neighbor : graph.get(node)) { + if (!visited.contains(neighbor)) { + queue.add(neighbor); + visited.add(node); + } + } + } + distance++; + } + return -1; + } +} diff --git a/Medium/Shortest Path in Binary Matrix.java b/Medium/Shortest Path in Binary Matrix.java index d73302d5..0be69c86 100644 --- a/Medium/Shortest Path in Binary Matrix.java +++ b/Medium/Shortest Path in Binary Matrix.java @@ -1,34 +1,40 @@ class Solution { - int[][] dirs = {{0,1},{0,-1},{1,0},{-1,0},{1,-1},{-1,1},{-1,-1},{1,1}}; - public int shortestPathBinaryMatrix(int[][] grid) { - int rows = grid.length; - int cols = grid[0].length; - if (grid[0][0] == 1 || grid[rows - 1][cols - 1] == 1) { - return -1; - } - boolean[][] visited = new boolean[rows][cols]; - Queue queue = new LinkedList<>(); - queue.add(new int[]{0, 0}); - visited[0][0] = true; - int steps = 0; - while (!queue.isEmpty()) { - int size = queue.size(); - while (size-- > 0) { - int[] removed = queue.remove(); - if (removed[0] == (rows - 1) && removed[1] == (cols - 1)) { - return steps + 1; + + private static final int[][] DIRS = {{0,1},{0,-1},{1,0},{-1,0},{1,-1},{-1,1},{-1,-1},{1,1}}; + + public int shortestPathBinaryMatrix(int[][] grid) { + int numRows = grid.length; + int numCols = grid[0].length; + if (grid[0][0] == 1 || grid[numRows - 1][numCols - 1] == 1) { + return -1; } - for (int i = 0; i < dirs.length; i++) { - int newX = removed[0] + dirs[i][0]; - int newY = removed[1] + dirs[i][1]; - if (newX >= 0 && newX < rows && newY >= 0 && newY < cols && !visited[newX][newY] && grid[newX][newY] == 0) { - queue.add(new int[]{newX, newY}); - visited[newX][newY] = true; - } + int shortestDistance = 0; + Queue queue = new LinkedList<>(); + queue.add(new int[]{0, 0}); + boolean[][] visited = new boolean[numRows][numCols]; + visited[0][0] = true; + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + int[] removed = queue.remove(); + if (removed[0] == (numRows - 1) && removed[1] == (numCols - 1)) { + return shortestDistance + 1; + } + for (int i = 0; i < DIRS.length; i++) { + int newX = removed[0] + DIRS[i][0]; + int newY = removed[1] + DIRS[i][1]; + if (isValidCoordinate(newX, newY, numRows, numCols, visited, grid)) { + queue.add(new int[]{newX, newY}); + visited[newX][newY] = true; + } + } + } + shortestDistance++; } - } - steps++; + return -1; + } + + private static boolean isValidCoordinate(int x, int y, int rows, int cols, boolean[][] visited, int[][] grid) { + return x >= 0 && x < rows && y >= 0 && y < cols && !visited[x][y] && grid[x][y] == 0; } - return -1; - } } diff --git a/Medium/Shortest Path with Alternating Colors.java b/Medium/Shortest Path with Alternating Colors.java index c2c3622a..63f670d0 100644 --- a/Medium/Shortest Path with Alternating Colors.java +++ b/Medium/Shortest Path with Alternating Colors.java @@ -1,72 +1,57 @@ class Solution { - private final Integer RED = 1; - private final Integer BLUE = 2; - public int[] shortestAlternatingPaths(int n, int[][] red_edges, int[][] blue_edges) { - Map> map = new HashMap<>(); - for (int[] edge : red_edges) { - map.computeIfAbsent(edge[0], k -> new ArrayList<>()).add(new Connection(edge[1], RED)); - } - for (int[] edge : blue_edges) { - map.computeIfAbsent(edge[0], k -> new ArrayList<>()).add(new Connection(edge[1], BLUE)); - } - int[] distances = new int[n]; - for (int i = 1; i < n; i++) { - distances[i] = getDistance(map, i, n); - } - return distances; - } - - private int getDistance(Map> map, int target, int n) { - int curr = 0; - int steps = 0; - boolean found = false; - Queue queue = new LinkedList<>(); - boolean[][] visited = new boolean[2][n]; - queue.add(new int[]{0, -1}); - while (!queue.isEmpty()) { - int size = queue.size(); - while (size-- > 0) { - int[] removed = queue.remove(); - if (removed[0] == target) { - found = true; - break; + + private static final Integer RED = 1; + private static final Integer BLUE = 2; + + public int[] shortestAlternatingPaths(int n, int[][] red_edges, int[][] blue_edges) { + Map> map = new HashMap<>(); + for (int[] edge : red_edges) { + map.computeIfAbsent(edge[0], k -> new ArrayList<>()).add(new Connection(edge[1], RED)); } - int color = removed[1]; - for (Connection connection : map.getOrDefault(removed[0], new ArrayList<>())) { - if (color == -1 && !visited[connection.color - 1][connection.val]) { - visited[connection.color - 1][connection.val] = true; - queue.add(connection.getArray()); - } - else if (color == 1 && connection.color != 1 && !visited[connection.color - 1][connection.val]) { - visited[connection.color - 1][connection.val] = true; - queue.add(connection.getArray()); - } - else if (color == 2 && connection.color != 2 && !visited[connection.color - 1][connection.val]) { - visited[connection.color - 1][connection.val] = true; - queue.add(connection.getArray()); - } + for (int[] edge : blue_edges) { + map.computeIfAbsent(edge[0], k -> new ArrayList<>()).add(new Connection(edge[1], BLUE)); + } + int[] distances = new int[n]; + for (int i = 1; i < n; i++) { + distances[i] = getDistance(map, i, n); } - } - if (found) { - break; - } - steps++; + return distances; } - return found ? steps : -1; - } -} - -class Connection { - int val; - int color; - - public Connection(int val, int color) { - this.val = val; - this.color = color; - } - - public int[] getArray() { - return new int[]{this.val, this.color}; - } + private int getDistance(Map> map, int target, int n) { + int steps = 0; + Queue queue = new LinkedList<>(); + boolean[][] visited = new boolean[2][n]; + queue.add(new int[]{0, -1}); + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + int[] removed = queue.remove(); + if (removed[0] == target) { + return steps; + } + int color = removed[1]; + for (Connection connection : map.getOrDefault(removed[0], new ArrayList<>())) { + if (color == -1 && !visited[connection.color - 1][connection.val]) { + visited[connection.color - 1][connection.val] = true; + queue.add(connection.getArray()); + } else if (color == 1 && connection.color != 1 && !visited[connection.color - 1][connection.val]) { + visited[connection.color - 1][connection.val] = true; + queue.add(connection.getArray()); + } else if (color == 2 && connection.color != 2 && !visited[connection.color - 1][connection.val]) { + visited[connection.color - 1][connection.val] = true; + queue.add(connection.getArray()); + } + } + } + steps++; + } + return -1; + } + + private record Connection(int val, int color) { + public int[] getArray() { + return new int[]{this.val, this.color}; + } + } } diff --git a/Medium/Shortest Subarray to be Removed to Make Array Sorted.java b/Medium/Shortest Subarray to be Removed to Make Array Sorted.java new file mode 100644 index 00000000..4ddb25e2 --- /dev/null +++ b/Medium/Shortest Subarray to be Removed to Make Array Sorted.java @@ -0,0 +1,18 @@ +class Solution { + public int findLengthOfShortestSubarray(int[] arr) { + int right = arr.length - 1; + while (right > 0 && arr[right] >= arr[right - 1]) { + right--; + } + int result = right; + int left = 0; + while (left < right && (left == 0 || arr[left - 1] <= arr[left])) { + while (right < arr.length && arr[left] > arr[right]) { + right++; + } + result = Math.min(result, right - left - 1); + left++; + } + return result; + } +} diff --git a/Medium/Shortest Unsorted Continuous Subarray.java b/Medium/Shortest Unsorted Continuous Subarray.java new file mode 100644 index 00000000..22fd54da --- /dev/null +++ b/Medium/Shortest Unsorted Continuous Subarray.java @@ -0,0 +1,21 @@ +class Solution { + public int findUnsortedSubarray(int[] nums) { + Stack stack = new Stack<>(); + int start = nums.length; + for (int i = 0; i < nums.length; i++) { + while (!stack.isEmpty() && nums[stack.peek()] > nums[i]) { + start = Math.min(start, stack.pop()); + } + stack.push(i); + } + stack.clear(); + int end = 0; + for (int i = nums.length - 1; i >= 0; i--) { + while (!stack.isEmpty() && nums[stack.peek()] < nums[i]) { + end = Math.max(end, stack.pop()); + } + stack.push(i); + } + return end - start > 0 ? end - start + 1 : 0; + } +} diff --git a/Medium/Shortest Way to Form String.java b/Medium/Shortest Way to Form String.java index c5f28f1f..e87eaf33 100644 --- a/Medium/Shortest Way to Form String.java +++ b/Medium/Shortest Way to Form String.java @@ -1,28 +1,23 @@ class Solution { - public int shortestWay(String source, String target) { - int count = 1; - int idx = 0; - int n = target.length(); - int sourceIdx = 0; - boolean match = false; - while (idx < n) { - if (source.charAt(sourceIdx) == target.charAt(idx)) { - idx++; - sourceIdx++; - match = true; - } - else { - sourceIdx++; - } - if (sourceIdx == source.length() && idx != n) { - if (!match) { - return -1; + public int shortestWay(String source, String target) { + Set letters = source.chars().mapToObj(c -> (char) c).collect(Collectors.toSet()); + int count = 0; + int sourceIdx = 0; + int targetIdx = 0; + while (targetIdx < target.length()) { + char targetLetter = target.charAt(targetIdx); + if (!letters.contains(targetLetter)) { + return -1; + } + if (targetLetter == source.charAt(sourceIdx)) { + targetIdx++; + } + sourceIdx++; + if (sourceIdx == source.length()) { + sourceIdx = 0; + count++; + } } - count++; - sourceIdx = 0; - match = false; - } + return count + (sourceIdx == 0 ? 0 : 1); } - return count; - } } diff --git a/Medium/Shortest Word Distance II.java b/Medium/Shortest Word Distance II.java index 7dbb3799..3a33f75d 100644 --- a/Medium/Shortest Word Distance II.java +++ b/Medium/Shortest Word Distance II.java @@ -1,33 +1,36 @@ class WordDistance { - Map> map; - public WordDistance(String[] words) { - map = new HashMap<>(); - for (int i = 0; i < words.length; i++) { - map.computeIfAbsent(words[i], k -> new ArrayList<>()).add(i); + + private Map> locations; + + public WordDistance(String[] wordsDict) { + this.locations = new HashMap<>(); + for (int i = 0; i < wordsDict.length; i++) { + this.locations.computeIfAbsent(wordsDict[i], k -> new ArrayList<>()).add(i); } } public int shortest(String word1, String word2) { - List idxList1 = map.get(word1); - List idxList2 = map.get(word2); - int idx1 = 0; - int idx2 = 0; - int minDiff = Math.abs(idxList1.get(idx1) - idxList2.get(idx2)); - while (idx1 < idxList1.size() && idx2 < idxList2.size()) { - minDiff = Math.min(minDiff, Math.abs(idxList1.get(idx1) - idxList2.get(idx2))); - if (idxList1.get(idx1) < idxList2.get(idx2)) { - idx1++; - } - else { - idx2++; + List indicesOne = this.locations.get(word1); + List indicesTwo = this.locations.get(word2); + int idxOne = 0; + int idxTwo = 0; + int minimumIndexDifference = Integer.MAX_VALUE; + while (idxOne < indicesOne.size() && idxTwo < indicesTwo.size()) { + minimumIndexDifference = Math.min( + minimumIndexDifference, + Math.abs(indicesOne.get(idxOne) - indicesTwo.get(idxTwo))); + if (indicesOne.get(idxOne) < indicesTwo.get(idxTwo)) { + idxOne++; + } else { + idxTwo++; } } - return minDiff; + return minimumIndexDifference; } } /** * Your WordDistance object will be instantiated and called as such: - * WordDistance obj = new WordDistance(words); + * WordDistance obj = new WordDistance(wordsDict); * int param_1 = obj.shortest(word1,word2); */ diff --git a/Medium/Shortest Word Distance III.java b/Medium/Shortest Word Distance III.java index f2b40359..fba93082 100644 --- a/Medium/Shortest Word Distance III.java +++ b/Medium/Shortest Word Distance III.java @@ -1,40 +1,24 @@ class Solution { - public int shortestWordDistance(String[] words, String word1, String word2) { - int idx1 = -1; - int idx2 = -1; - boolean sameWord = word1.equals(word2); - int n = words.length; - int minDiff = Integer.MAX_VALUE; - for (int i = 0; i < words.length; i++) { - if (words[i].equals(word1)) { - if (sameWord) { - if (idx1 == -1) { - idx1 = i; - } + public int shortestWordDistance(String[] wordsDict, String word1, String word2) { + int idxOne = -1; + int idxTwo = -1; + int minDistance = Integer.MAX_VALUE; + boolean sameWord = word1.equals(word2); + for (int i = 0; i < wordsDict.length; i++) { + if (wordsDict[i].equals(word1)) { + idxOne = sameWord ? (idxOne == -1 ? i : idxOne) : i; + } + if (wordsDict[i].equals(word2)) { + idxTwo = sameWord ? (idxOne != i ? i : idxTwo) : i; + } + if (idxOne != -1 && idxTwo != -1) { + minDistance = Math.min(minDistance, Math.abs(idxOne - idxTwo)); + if (sameWord) { + idxOne = idxTwo; + idxTwo = -1; + } + } } - else { - idx1 = i; - } - } - if (words[i].equals(word2)) { - if (sameWord) { - if (idx1 != i) { - idx2 = i; - } - } - else { - idx2 = i; - } - } - if (idx1 != -1 && idx2 != -1) { - minDiff = Math.min(minDiff, Math.abs(idx1 - idx2)); - if (sameWord) { - idx1 = idx2; - idx2 = -1; - } - } + return minDistance; } - return minDiff; - } } - diff --git a/Medium/Simple Bank System.java b/Medium/Simple Bank System.java new file mode 100644 index 00000000..a674aa0f --- /dev/null +++ b/Medium/Simple Bank System.java @@ -0,0 +1,44 @@ +class Bank { + + private long[] balance; + public Bank(long[] balance) { + this.balance = balance; + } + + public boolean transfer(int account1, int account2, long money) { + if (isInvalidAccount(account1) || isInvalidAccount(account2) || balance[account1 - 1] < money) { + return false; + } + balance[account1 - 1] -= money; + balance[account2 - 1] += money; + return true; + } + + public boolean deposit(int account, long money) { + if (isInvalidAccount(account)) { + return false; + } + balance[account - 1] += money; + return true; + } + + public boolean withdraw(int account, long money) { + if (isInvalidAccount(account) || balance[account - 1] < money) { + return false; + } + balance[account - 1] -= money; + return true; + } + + private boolean isInvalidAccount(int accountId) { + return !(accountId >= 1 && accountId <= this.balance.length); + } +} + +/** + * Your Bank object will be instantiated and called as such: + * Bank obj = new Bank(balance); + * boolean param_1 = obj.transfer(account1,account2,money); + * boolean param_2 = obj.deposit(account,money); + * boolean param_3 = obj.withdraw(account,money); + */ diff --git a/Medium/Simplify Path.java b/Medium/Simplify Path.java index b272d133..b04ccd5e 100644 --- a/Medium/Simplify Path.java +++ b/Medium/Simplify Path.java @@ -1,35 +1,23 @@ class Solution { - public String simplifyPath(String path) { - Stack stack = new Stack<>(); - StringBuilder sb = new StringBuilder(); - int idx = 0; - int n = path.length(); - while (idx < n) { - if (path.charAt(idx) == '/') { - idx++; - while (idx < n && path.charAt(idx) != '/') { - sb.append(path.charAt(idx++)); + public String simplifyPath(String path) { + Stack stack = new Stack<>(); + String[] splits = path.split("\\/"); + for (String split : splits) { + if (split.equals(".") || split.equals("/") || split.isBlank()) { + continue; + } + if (split.equals("..")) { + if (!stack.isEmpty()) { + stack.pop(); + } + } else { + stack.push(split); + } } - String dir = sb.toString(); - sb.setLength(0); - if (dir.equals("..")) { - if (!stack.isEmpty()) { - stack.pop(); - } + StringBuilder sb = new StringBuilder(); + while (!stack.isEmpty()) { + sb.insert(0, stack.pop()).insert(0, "/"); } - else if (dir.equals(".") || dir.length() == 0) { - continue; - } - else { - stack.push(dir); - } - } - } - sb = new StringBuilder(); - while (!stack.isEmpty()) { - sb.insert(0, stack.pop()); - sb.insert(0, "/"); + return sb.length() == 0 ? "/" : sb.toString(); } - return sb.length() > 0 ? sb.toString() : "/"; - } } diff --git a/Medium/Single Element in a Sorted Array.java b/Medium/Single Element in a Sorted Array.java index 3565e0b3..924794d3 100644 --- a/Medium/Single Element in a Sorted Array.java +++ b/Medium/Single Element in a Sorted Array.java @@ -1,25 +1,25 @@ class Solution { - public int singleNonDuplicate(int[] nums) { - if (nums.length == 1) { - return nums[0]; + public int singleNonDuplicate(int[] nums) { + int start = 0; + int end = nums.length - 1; + while (start < end) { + int mid = (end - start) / 2 + start; + if (nums[mid + 1] == nums[mid]) { + if ((end - mid) % 2 == 0) { + start = mid + 2; + } else { + end = mid - 1; + } + } else if (nums[mid - 1] == nums[mid]) { + if ((end - mid) % 2 == 0) { + end = mid - 2; + } else { + start = mid + 1; + } + } else { + return nums[mid]; + } + } + return nums[start]; } - return binarySearchHelper(nums, 0, nums.length - 1); - } - - private int binarySearchHelper(int[] nums, int start, int end) { - if (start > end) { - return Integer.MIN_VALUE; - } - int mid = (start + end) / 2; - if (mid == 0 && mid + 1 < nums.length && nums[mid] != nums[mid + 1]) { - return nums[mid]; - } - if (mid == nums.length - 1 && mid - 1 >= 0 && nums[mid] != nums[mid - 1]) { - return nums[mid]; - } - if (mid + 1 < nums.length && nums[mid] != nums[mid + 1] && mid - 1 >= 0 && nums[mid] != nums[mid - 1]) { - return nums[mid]; - } - return Math.max(binarySearchHelper(nums, start, mid - 1), binarySearchHelper(nums, mid + 1, end)); - } } diff --git a/Medium/Single Number III.java b/Medium/Single Number III.java index 7caf6b85..0409a84a 100644 --- a/Medium/Single Number III.java +++ b/Medium/Single Number III.java @@ -1,15 +1,17 @@ class Solution { public int[] singleNumber(int[] nums) { - Set set = new HashSet<>(); + int xorValue = Integer.highestOneBit(Arrays.stream(nums) + .boxed() + .reduce((a, b) -> a ^ b) + .orElse(0)); + int[] result = new int[2]; for (int num : nums) { - if (set.contains(num)) { - set.remove(num); - } - else { - set.add(num); + if ((xorValue & num) == 0) { + result[0] ^= num; + } else { + result[1] ^= num; } } - Iterator iter = set.iterator(); - return new int[]{iter.next(), iter.next()}; + return result; } } diff --git a/Medium/Smallest Common Region.java b/Medium/Smallest Common Region.java new file mode 100644 index 00000000..4d8ce894 --- /dev/null +++ b/Medium/Smallest Common Region.java @@ -0,0 +1,32 @@ +class Solution { + public String findSmallestRegion(List> regions, String region1, String region2) { + Map regionToParentMap = new HashMap<>(); + for (List region : regions) { + String parent = region.getFirst(); + for (int i = 1; i < region.size(); i++) { + regionToParentMap.put(region.get(i), parent); + } + } + List pathOne = trace(region1, regionToParentMap); + List pathTwo = trace(region2, regionToParentMap); + int idxOne = 0; + int idxTwo = 0; + while (idxOne < pathOne.size() && idxTwo < pathTwo.size() && pathOne.get(idxOne).equals(pathTwo.get(idxTwo))) { + idxOne++; + idxTwo++; + } + return pathOne.get(idxOne - 1); + } + + private List trace(String region, Map regionToParentMap) { + List path = new ArrayList<>(); + path.add(region); + while (regionToParentMap.containsKey(region)) { + String parent = regionToParentMap.get(region); + path.add(parent); + region = parent; + } + Collections.reverse(path); + return path; + } +} diff --git a/Medium/Smallest Integer Divisible by K.java b/Medium/Smallest Integer Divisible by K.java new file mode 100644 index 00000000..52575545 --- /dev/null +++ b/Medium/Smallest Integer Divisible by K.java @@ -0,0 +1,15 @@ +class Solution { + public int smallestRepunitDivByK(int K) { + if (K % 2 == 0 || K % 5 == 0) { + return -1; + } + int remainder = 0; + for (int n = 1; n <= K; n++) { + remainder = (remainder * 10 + 1) % K; + if (remainder == 0) { + return n; + } + } + return -1; + } +} diff --git a/Medium/Smallest Number in Infinite Set.java b/Medium/Smallest Number in Infinite Set.java new file mode 100644 index 00000000..2555f5ce --- /dev/null +++ b/Medium/Smallest Number in Infinite Set.java @@ -0,0 +1,34 @@ +class SmallestInfiniteSet { + + private final PriorityQueue pq; + private int current; + + public SmallestInfiniteSet() { + this.pq = new PriorityQueue<>(); + this.current = 1; + } + + public int popSmallest() { + int result = current; + if (!pq.isEmpty() && pq.peek() < current) { + result = pq.poll(); + } else { + current++; + } + while (!pq.isEmpty() && pq.peek() == result) { + pq.poll(); + } + return result; + } + + public void addBack(int num) { + pq.add(num); + } +} + +/** + * Your SmallestInfiniteSet object will be instantiated and called as such: + * SmallestInfiniteSet obj = new SmallestInfiniteSet(); + * int param_1 = obj.popSmallest(); + * obj.addBack(num); + */ diff --git a/Medium/Smallest String Starting From Leaf.java b/Medium/Smallest String Starting From Leaf.java index d890af9e..6948a960 100644 --- a/Medium/Smallest String Starting From Leaf.java +++ b/Medium/Smallest String Starting From Leaf.java @@ -4,36 +4,33 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - public String smallestFromLeaf(TreeNode root) { - return helper(root); + public String smallestFromLeaf(TreeNode root) { + return dfs(root, ""); + } + + private String dfs(TreeNode root, String curr) { + if (root == null) { + return curr; } - - private String helper(TreeNode root) { - if (root == null) { - return null; - } - - char ch = (char) (97 + root.val); - String leftVal = helper(root.left); - String rightVal = helper(root.right); - - if (leftVal == null && rightVal == null) { - return "" + ch; - } - - if (root.left == null || root.right == null) { - return rightVal == null ? leftVal + ch : rightVal + ch; - } - - if (rightVal.compareTo(leftVal) > 0) { - return leftVal + ch; - } - else { - return rightVal + ch; - } + curr = "" + (char)(97 + root.val) + curr; + if (root.left == null && root.right == null) { + return curr; + } else if (root.left == null || root.right == null) { + return root.left == null ? dfs(root.right, curr) : dfs(root.left, curr); + } else { + String left = dfs(root.left, curr); + String right = dfs(root.right, curr); + return left.compareTo(right) <= 0 ? left : right; } + } } diff --git a/Medium/Smallest String With A Given Numeric Value.java b/Medium/Smallest String With A Given Numeric Value.java new file mode 100644 index 00000000..6957c53c --- /dev/null +++ b/Medium/Smallest String With A Given Numeric Value.java @@ -0,0 +1,12 @@ +class Solution { + public String getSmallestString(int n, int k) { + StringBuilder sb = new StringBuilder(); + while (k > 0) { + int maxPossible = Math.min(k - n + 1, 26); + sb.append((char) ('a' + maxPossible - 1)); + k -= maxPossible; + n--; + } + return sb.reverse().toString(); + } +} diff --git a/Medium/Smallest String With Swaps.java b/Medium/Smallest String With Swaps.java new file mode 100644 index 00000000..e9cea772 --- /dev/null +++ b/Medium/Smallest String With Swaps.java @@ -0,0 +1,60 @@ +class Solution { + public String smallestStringWithSwaps(String s, List> pairs) { + int n = s.length(); + DisjointSet disjointSet = new DisjointSet(n); + for (List pair : pairs) { + disjointSet.union(pair.get(0), pair.get(1)); + } + Map> map = new HashMap<>(); + for (int i = 0; i < n; i++) { + int root = disjointSet.find(i); + map.computeIfAbsent(root, k -> new PriorityQueue<>()).offer(s.charAt(i)); + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + sb.append(map.get(disjointSet.find(i)).poll()); + } + return sb.toString(); + } + + private static final class DisjointSet { + + private final int[] root; + private final int[] rank; + public int unionCount; + + public DisjointSet(int size) { + this.root = new int[size]; + this.rank = new int[size]; + for (int i = 0; i < size; i++) { + this.root[i] = i; + this.rank[i] = 1; + } + this.unionCount = size; + } + + public void union(int nodeOne, int nodeTwo) { + int rootOne = find(nodeOne); + int rootTwo = find(nodeTwo); + if (rootOne != rootTwo) { + if (this.rank[rootOne] > this.rank[rootTwo]) { + this.root[rootTwo] = rootOne; + } else if (this.rank[rootOne] < this.rank[rootTwo]) { + this.root[rootOne] = rootTwo; + } else { + this.root[rootTwo] = rootOne; + this.rank[rootOne]++; + } + this.unionCount--; + } + } + + + public int find(int node) { + if (node == root[node]) { + return node; + } + return root[node] = find(root[node]); + } + } +} diff --git a/Medium/Smallest Subtree with all the Deepest Nodes.java b/Medium/Smallest Subtree with all the Deepest Nodes.java index 3999f22e..5ad5f59d 100644 --- a/Medium/Smallest Subtree with all the Deepest Nodes.java +++ b/Medium/Smallest Subtree with all the Deepest Nodes.java @@ -14,41 +14,32 @@ * } */ class Solution { - Map map; - int maxDepth; public TreeNode subtreeWithAllDeepest(TreeNode root) { - map = new HashMap<>(); - maxDepth = -1; - map.put(null, -1); - dfs(root, null); - return helper(root); + return dfs(root).node; } - private void dfs(TreeNode root, TreeNode parent) { + private NodeResult dfs(TreeNode root) { if (root == null) { - return; + return new NodeResult(null, 0); } - map.put(root, map.get(parent) + 1); - maxDepth = Math.max(maxDepth, map.get(root)); - dfs(root.left, root); - dfs(root.right, root); - } - - private TreeNode helper(TreeNode root) { - if (root == null || map.get(root) == maxDepth) { - return root; - } - TreeNode left = helper(root.left); - TreeNode right = helper(root.right); - if (left != null && right != null) { - return root; + NodeResult leftResult = dfs(root.left); + NodeResult rightResult = dfs(root.right); + if (leftResult.distance > rightResult.distance) { + return new NodeResult(leftResult.node, leftResult.distance + 1); } - if (left != null) { - return left; + if (leftResult.distance < rightResult.distance) { + return new NodeResult(rightResult.node, rightResult.distance + 1); } - if (right != null) { - return right; + return new NodeResult(root, rightResult.distance + 1); + } + + private static class NodeResult { + TreeNode node; + int distance; + + public NodeResult(TreeNode node, int distance) { + this.node = node; + this.distance = distance; } - return null; } } diff --git a/Medium/Smallest Value of the Rearranged Number.java b/Medium/Smallest Value of the Rearranged Number.java new file mode 100644 index 00000000..13dfdc46 --- /dev/null +++ b/Medium/Smallest Value of the Rearranged Number.java @@ -0,0 +1,35 @@ +class Solution { + public long smallestNumber(long num) { + return num < 0 ? + getArrangement(Math.abs(num), (o1, o2) -> (int) (o2 - o1), true) * -1 : + getArrangement(num, (o1, o2) -> (int) (o1 - o2), false); + } + + private long getArrangement(long num, Comparator comparator, boolean zeroAtEnd) { + PriorityQueue pq = new PriorityQueue<>(comparator); + long zeroMultiple = 1; + while (num > 0) { + long remainder = num % 10; + if (remainder == 0) { + zeroMultiple *= 10; + } else { + pq.add(remainder); + } + num /= 10; + } + long result = 0; + if (!pq.isEmpty()) { + result = result * 10 + pq.poll(); + } + if (!zeroAtEnd) { + result *= zeroMultiple; + } + while (!pq.isEmpty()) { + result = result * 10 + pq.poll(); + } + if (zeroAtEnd) { + result *= zeroMultiple; + } + return result; + } +} diff --git a/Medium/Snapshot Array.java b/Medium/Snapshot Array.java index d735dde3..282b6476 100644 --- a/Medium/Snapshot Array.java +++ b/Medium/Snapshot Array.java @@ -1,26 +1,28 @@ class SnapshotArray { - TreeMap[] A; - int snapId; - public SnapshotArray(int length) { - A = new TreeMap[length]; - snapId = 0; - for (int i = 0; i < length; i++) { - A[i] = new TreeMap(); - A[i].put(0, 0); + + private final TreeMap[] db; + private int currentSnapId; + + public SnapshotArray(int length) { + db = new TreeMap[length]; + for (int i = 0; i < length; i++) { + db[i] = new TreeMap(); + db[i].put(0, 0); + } + this.currentSnapId = 0; } - } - public void set(int index, int val) { - A[index].put(snapId, val); - } + public void set(int index, int val) { + db[index].put(currentSnapId, val); + } - public int snap() { - return snapId++; - } + public int snap() { + return currentSnapId++; + } - public int get(int index, int snap_id) { - return A[index].floorEntry(snap_id).getValue(); - } + public int get(int index, int snap_id) { + return db[index].floorEntry(snap_id).getValue(); + } } /** diff --git a/Medium/Solve the Equation.java b/Medium/Solve the Equation.java index e5edc253..bc506e04 100644 --- a/Medium/Solve the Equation.java +++ b/Medium/Solve the Equation.java @@ -1,93 +1,46 @@ class Solution { - public String solveEquation(String equation) { - int leftXCount = 0; - int rightXCount = 0; - int leftNumCount = 0; - int rightNumCount = 0; - boolean switchDone = false; - int sign = 1; - StringBuilder sb = new StringBuilder(); - - for (char c : equation.toCharArray()) { - if (c == '=') { - if (sb.length() > 0) { - leftNumCount += sign * Integer.parseInt(sb.toString()); - sb.setLength(0); - sign = 1; - } - - switchDone = true; - continue; - } - - if (c == 'x') { - if (switchDone) { - rightXCount += sign * (sb.length() > 0 ? Integer.parseInt(sb.toString()) : 1); - } - else { - leftXCount += sign * (sb.length() > 0 ? Integer.parseInt(sb.toString()) : 1); - } - - sign = 1; - sb.setLength(0); - } - else if (Character.isDigit(c)) { - sb.append(c); - } - else if (c == '+' || c == '-') { - if (sb.length() > 0) { - if (switchDone) { - rightNumCount += sign * (Integer.parseInt(sb.toString())); - } - else { - leftNumCount += sign * (Integer.parseInt(sb.toString())); - } - - sb.setLength(0); - } - - sign = c == '+' ? 1 : -1; - } - } - - if (sb.length() > 0) { - rightNumCount += sign * Integer.parseInt(sb.toString()); - } - - if (leftXCount == rightXCount && leftNumCount != rightNumCount) { - return "No solution"; - } - else if (leftXCount == rightXCount && leftNumCount == rightNumCount) { - return "Infinite solutions"; - } - else { - int totalXCount = leftXCount - rightXCount; - int totalValueCount = rightNumCount - leftNumCount; - - int gcd = getGcd(totalXCount, totalValueCount); - if (gcd != 0) { - totalXCount /= gcd; - totalValueCount /= gcd; - } - - if (totalXCount < 0) { - totalXCount *= -1; - totalValueCount *= -1; - } - - return new StringBuilder() - .append(totalXCount > 1 ? totalXCount : "") - .append("x=") - .append(totalValueCount) - .toString(); - } + public String solveEquation(String equation) { + int[] equationFirst = parseEquation(equation.split("=")[0]); + int[] equationSecond = parseEquation(equation.split("=")[1]); + int constantPart = equationSecond[1] - equationFirst[1]; + int variablePart = equationFirst[0] - equationSecond[0]; + if (variablePart == 0) { + return constantPart == 0 ? "Infinite solutions" : "No solution"; } - - private int getGcd(int totalXCount, int totalValueCount) { - if (totalXCount == 0) { - return totalValueCount; + int sign = (variablePart < 0 && constantPart < 0) || (variablePart > 0 && constantPart > 0) ? 1 : -1; + if (Math.abs(constantPart) % Math.abs(variablePart) == 0) { + constantPart = Math.abs(constantPart) / Math.abs(variablePart); + variablePart = 1; + } + return (variablePart > 1 ? variablePart : "") + "x=" + sign * constantPart; + } + + private int[] parseEquation(String s) { + int variablePart = 0; + int constantPart = 0; + int sign = 1; + int n = s.length(); + for (int idx = 0; idx < n;) { + if (s.charAt(idx) == 'x') { + variablePart += sign; + idx++; + sign = 1; + } else if (Character.isDigit(s.charAt(idx))) { + int num = 0; + while (idx < n && Character.isDigit(s.charAt(idx))) { + num = num * 10 + Character.getNumericValue(s.charAt(idx++)); + } + if (idx != n && s.charAt(idx) == 'x') { + variablePart += sign * num; + idx++; + } else { + constantPart += sign * num; } - - return getGcd(totalValueCount % totalXCount, totalXCount); + sign = 1; + } else { + sign = s.charAt(idx++) == '+' ? 1 : -1; + } } + return new int[]{variablePart, constantPart}; + } } diff --git a/Medium/Solving Questions With Brainpower.java b/Medium/Solving Questions With Brainpower.java new file mode 100644 index 00000000..76e640d1 --- /dev/null +++ b/Medium/Solving Questions With Brainpower.java @@ -0,0 +1,19 @@ +class Solution { + public long mostPoints(int[][] questions) { + Long[] dp = new Long[questions.length]; + return helper(questions, 0, dp); + } + + private long helper(int[][] questions, int idx, Long[] dp) { + if (idx >= questions.length) { + return 0; + } + if (dp[idx] != null) { + return dp[idx]; + } + return dp[idx] = Math.max( + questions[idx][0] + helper(questions, idx + questions[idx][1] + 1, dp), + helper(questions, idx + 1, dp) + ); + } +} diff --git a/Medium/Sort An Array.java b/Medium/Sort An Array.java index 7d4a1a41..a906afc4 100644 --- a/Medium/Sort An Array.java +++ b/Medium/Sort An Array.java @@ -1,18 +1,39 @@ class Solution { public int[] sortArray(int[] nums) { - int[] counter = new int[2 * 50000 + 1]; - for (int num : nums) { - counter[50000 + num]++; + mergeSort(nums, 0, nums.length - 1); + return nums; + } + + private void mergeSort(int[] nums, int start, int end) { + if (end - start <= 0) { + return; } - + int mid = start + (end - start) / 2; + mergeSort(nums, start, mid); + mergeSort(nums, mid + 1, end); + merge(nums, start, mid, end); + } + + private void merge(int[] nums, int start, int mid, int end) { + int left = start; + int right = mid + 1; + int[] temp = new int[end - start + 1]; int idx = 0; - for (int i = 0; i < counter.length; i++) { - int val = i > 50000 ? i - 50000 : -(50000 - i); - while (counter[i]-- > 0) { - nums[idx++] = val; + while (left <= mid && right <= end) { + if (nums[left] < nums[right]) { + temp[idx++] = nums[left++]; + } else { + temp[idx++] = nums[right++]; } } - - return nums; + while (left <= mid) { + temp[idx++] = nums[left++]; + } + while (right <= end) { + temp[idx++] = nums[right++]; + } + for (int i = start; i <= end; i++) { + nums[i] = temp[i - start]; + } } } diff --git a/Medium/Sort Characters By Frequency.java b/Medium/Sort Characters By Frequency.java index 4d0ed2b2..7c0978bc 100644 --- a/Medium/Sort Characters By Frequency.java +++ b/Medium/Sort Characters By Frequency.java @@ -1,20 +1,32 @@ class Solution { - public String frequencySort(String s) { - Map map = new HashMap<>(); - for (char c : s.toCharArray()) { - map.put(c, map.getOrDefault(c, 0) + 1); + + private static final String ALL_LETTERS = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + public String frequencySort(String s) { + Map map = new HashMap<>(); + int maxFrequency = 0; + for (char c : s.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); + maxFrequency = Math.max(maxFrequency, map.get(c)); + } + List[] frequencyToChar = new List[maxFrequency + 1]; + for (char c : map.keySet()) { + if (frequencyToChar[map.get(c)] == null) { + frequencyToChar[map.get(c)] = new ArrayList<>(); + } + frequencyToChar[map.get(c)].add(c); + } + StringBuilder sb = new StringBuilder(); + for (int i = maxFrequency; i > 0; i--) { + List characters = frequencyToChar[i] == null ? + new ArrayList<>() : frequencyToChar[i]; + for (char c : characters) { + for (int j = 0; j < i; j++) { + sb.append(c); + } + } + } + return sb.toString(); } - PriorityQueue pq = new PriorityQueue<>((o1, o2) -> map.get(o2) - map.get(o1)); - pq.addAll(map.keySet()); - StringBuilder sb = new StringBuilder(); - while (!pq.isEmpty()) { - char c = pq.poll(); - int count = map.get(c); - while (count-- > 0) { - sb.append(c); - } - } - return sb.toString(); - } } - diff --git a/Medium/Sort Colors.java b/Medium/Sort Colors.java index 6fc66d88..6bfe64e8 100644 --- a/Medium/Sort Colors.java +++ b/Medium/Sort Colors.java @@ -1,25 +1,19 @@ class Solution { public void sortColors(int[] nums) { int zeroIdx = 0; - int curr = 0; - int n = nums.length - 1; - int twoIdx = n; - while (curr <= twoIdx) { - if (nums[curr] == 0) { - swap(nums, curr++, zeroIdx++); - } - else if (nums[curr] == 2) { - swap(nums, curr, twoIdx--); - } - else { - curr++; + int twoIdx = nums.length - 1; + for (int i = 0; i <= twoIdx; ) { + if (nums[i] == 0 && i != zeroIdx) { + int temp = nums[zeroIdx]; + nums[zeroIdx++] = nums[i]; + nums[i] = temp; + } else if (nums[i] == 2 && i != twoIdx) { + int temp = nums[twoIdx]; + nums[twoIdx--] = nums[i]; + nums[i] = temp; + } else { + i++; } } } - - private void swap(int[] nums, int idx1, int idx2) { - int temp = nums[idx1]; - nums[idx1] = nums[idx2]; - nums[idx2] = temp; - } } diff --git a/Medium/Sort Integers by The Power Value.java b/Medium/Sort Integers by The Power Value.java new file mode 100644 index 00000000..aa9a5fa6 --- /dev/null +++ b/Medium/Sort Integers by The Power Value.java @@ -0,0 +1,25 @@ +class Solution { + public int getKth(int lo, int hi, int k) { + Map cache = new HashMap<>(); + cache.put(1, 0); + PriorityQueue pq = new PriorityQueue<>( + Comparator.comparingInt((Integer o) -> cache.get(o)).thenComparingInt(o -> o)); + for (int i = lo; i <= hi; i++) { + calculateSteps(cache, i); + pq.add(i); + } + while (!pq.isEmpty() && k-- > 1) { + pq.poll(); + } + return pq.peek(); + } + + private int calculateSteps(Map cache, int num) { + if (cache.containsKey(num)) { + return cache.get(num); + } + int numOfSteps = 1 + calculateSteps(cache, (num % 2 == 0 ? num / 2 : num * 3 + 1)); + cache.put(num, numOfSteps); + return cache.get(num); + } +} diff --git a/Medium/Sort Linked List Already Sorted Using Absolute Values.java b/Medium/Sort Linked List Already Sorted Using Absolute Values.java new file mode 100644 index 00000000..fd43f251 --- /dev/null +++ b/Medium/Sort Linked List Already Sorted Using Absolute Values.java @@ -0,0 +1,25 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode sortLinkedList(ListNode head) { + ListNode curr = head; + while (curr != null && curr.next != null){ + if (curr.next.val < 0) { + // Make a new head with negative value and assign its next pointer to current head + head = new ListNode(curr.next.val,head); + curr.next = curr.next.next; + } else { + curr = curr.next; + } + } + return head; + } +} diff --git a/Medium/Sort List.java b/Medium/Sort List.java index 8a5a9166..013db8f6 100644 --- a/Medium/Sort List.java +++ b/Medium/Sort List.java @@ -3,26 +3,51 @@ * public class ListNode { * int val; * ListNode next; - * ListNode(int x) { val = x; } + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { - public ListNode sortList(ListNode head) { - ArrayList arr = new ArrayList<>(); - ListNode curr = head; - while (curr != null) { - arr.add(curr.val); - curr = curr.next; - } - - Collections.sort(arr); - - curr = head; - for (int i=0;i priorityQueue = new PriorityQueue<>((o1, o2) -> { + if (o1[0] != o2[0]) { + return o1[0] - o2[0]; + } + return o1[1] - o2[1]; + }); + for (int i = 0; i < nums.length; i++) { + priorityQueue.add(new int[]{getUpdatedNumAfterMapping(nums[i], mapping), i, nums[i]}); + } + for (int i = 0; i < nums.length; i++) { + nums[i] = priorityQueue.poll()[2]; + } + return nums; + } + + private int getUpdatedNumAfterMapping(Integer original, int[] mapping) { + if (original <= 9) { + return mapping[original]; + } + int updatedNum = 0; + int factor = 1; + while (original > 0){ + updatedNum += mapping[original % 10] * factor; + factor *= 10; + original /= 10; + } + return updatedNum; + } +} diff --git a/Medium/Sort the Matrix Diagonally.java b/Medium/Sort the Matrix Diagonally.java new file mode 100644 index 00000000..003410db --- /dev/null +++ b/Medium/Sort the Matrix Diagonally.java @@ -0,0 +1,45 @@ +class Solution { + public int[][] diagonalSort(int[][] mat) { + int numRows = mat.length; + int numCols = mat[0].length; + for (int i = 0; i < numRows; i++) { + sortDiagonal(i, 0, mat); + } + for (int i = 0; i < numCols; i++) { + sortDiagonal(0, i, mat); + } + return mat; + } + + private void sortDiagonal(int row, int col, int[][] mat) { + int numRows = mat.length; + int numCols = mat[0].length; + List diagonal = new ArrayList<>(); + int diagonalLength = Math.min(numRows - row, numCols - col); + for (int i = 0; i < diagonalLength; i++) { + diagonal.add(mat[row + i][col + i]); + } + diagonal = countingSort(diagonal); + for (int i = 0; i < diagonalLength; i++) { + mat[row + i][col + i] = diagonal.get(i); + } + } + + private List countingSort(List list) { + int min = 1; + int max = 100; + int range = max - min + 1; + int[] frequency = new int[range]; + for (int num : list) { + frequency[num - min]++; + } + List sortedList = new ArrayList<>(); + for (int i = 0; i < range; i++) { + int count = frequency[i]; + while (count-- > 0) { + sortedList.add(i + min); + } + } + return sortedList; + } +} diff --git a/Medium/Sort the Students by Their Kth Score.java b/Medium/Sort the Students by Their Kth Score.java new file mode 100644 index 00000000..7c4f83e9 --- /dev/null +++ b/Medium/Sort the Students by Their Kth Score.java @@ -0,0 +1,6 @@ +class Solution { + public int[][] sortTheStudents(int[][] score, int k) { + Arrays.sort(score, (o1, o2) -> o2[k] - o1[k]); + return score; + } +} diff --git a/Medium/Sparse Matrix Multiplication.java b/Medium/Sparse Matrix Multiplication.java index e1e20566..d612b920 100644 --- a/Medium/Sparse Matrix Multiplication.java +++ b/Medium/Sparse Matrix Multiplication.java @@ -1,20 +1,15 @@ class Solution { - public int[][] multiply(int[][] A, int[][] B) { - int m = A.length; - int n = A[0].length; - int nB = B[0].length; - int[][] C = new int[m][nB]; - for(int i = 0; i < m; i++) { - for(int k = 0; k < n; k++) { - if (A[i][k] != 0) { - for (int j = 0; j < nB; j++) { - if (B[k][j] != 0) { - C[i][j] += A[i][k] * B[k][j]; - } + public int[][] multiply(int[][] mat1, int[][] mat2) { + int[][] result = new int[mat1.length][mat2[0].length]; + for (int i = 0; i < mat1.length; i++) { + for (int j = 0; j < mat1[0].length; j++) { + if (mat1[i][j] != 0) { + for (int k = 0; k < mat2[0].length; k++) { + result[i][k] += mat1[i][j] * mat2[j][k]; } } } } - return C; + return result; } } diff --git a/Medium/Spiral Matrix II.java b/Medium/Spiral Matrix II.java index ffa09b62..636fbb69 100644 --- a/Medium/Spiral Matrix II.java +++ b/Medium/Spiral Matrix II.java @@ -1,29 +1,33 @@ class Solution { - public int[][] generateMatrix(int n) { - int[][] ans = new int[n][n]; - int left = 0; - int top = 0; - int right = n -1; - int down = n - 1; - int count = 1; - while (left <= right) { - for (int j = left; j <= right; j ++) { - ans[top][j] = count++; - } - top++; - for (int i = top; i <= down; i ++) { - ans[i][right] = count ++; - } - right--; - for (int j = right; j >= left; j --) { - ans[down][j] = count ++; - } - down--; - for (int i = down; i >= top; i --) { - ans[i][left] = count ++; - } - left++; + public int[][] generateMatrix(int n) { + int[][] result = new int[n][n]; + int rowStart = 0; + int rowEnd = n - 1; + int colStart = 0; + int colEnd = n - 1; + int value = 1; + while (rowStart <= rowEnd && colStart <= colEnd) { + for (int i = colStart; i <= colEnd; i++) { + result[rowStart][i] = value++; + } + rowStart++; + for (int i = rowStart; i <= rowEnd; i++) { + result[i][colEnd] = value++; + } + colEnd--; + if (rowStart <= rowEnd) { + for (int i = colEnd; i >= colStart; i--) { + result[rowEnd][i] = value++; + } + rowEnd--; + } + if (colStart <= colEnd) { + for (int i = rowEnd; i >= rowStart; i--) { + result[i][colStart] = value++; + } + colStart++; + } + } + return result; } - return ans; - } } diff --git a/Medium/Spiral Matrix IV.java b/Medium/Spiral Matrix IV.java new file mode 100644 index 00000000..5136b493 --- /dev/null +++ b/Medium/Spiral Matrix IV.java @@ -0,0 +1,45 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public int[][] spiralMatrix(int m, int n, ListNode head) { + int[][] result = new int[m][n]; + for (int i = 0; i < m; i++) { + Arrays.fill(result[i], -1); + } + int topRow = 0; + int bottomRow = m - 1; + int leftColumn = 0; + int rightColumn = n - 1; + while (head != null) { + for (int col = leftColumn; col <= rightColumn && head != null; col++) { + result[topRow][col] = head.val; + head = head.next; + } + topRow++; + for (int row = topRow; row <= bottomRow && head != null; row++) { + result[row][rightColumn] = head.val; + head = head.next; + } + rightColumn--; + for (int col = rightColumn; col >= leftColumn && head != null; col--) { + result[bottomRow][col] = head.val; + head = head.next; + } + bottomRow--; + for (int row = bottomRow; row >= topRow && head != null; row--) { + result[row][leftColumn] = head.val; + head = head.next; + } + leftColumn++; + } + return result; + } +} diff --git a/Medium/Spiral Matrix.java b/Medium/Spiral Matrix.java index 4054cc83..252374fb 100644 --- a/Medium/Spiral Matrix.java +++ b/Medium/Spiral Matrix.java @@ -1,64 +1,32 @@ class Solution { public List spiralOrder(int[][] matrix) { - List list = new ArrayList<>(); - - if (matrix.length == 0 || matrix[0].length == 0) { - return list; - } - - int i = 0; - int j = 0; - int top = 0; - int bottom = matrix.length; - int left = 0; - int right = matrix[0].length; - int dir = 0; - int count = 0; - int limit = matrix.length * matrix[0].length; - - while (count < limit) { - if (dir == 0) { - while (j < right) { - list.add(matrix[i][j++]); - count++; - } - dir++; - right--; - i++; - j--; + List result = new ArrayList<>(); + int rowStart = 0; + int rowEnd = matrix.length - 1; + int colStart = 0; + int colEnd = matrix[0].length - 1; + while (rowStart <= rowEnd && colStart <= colEnd) { + for (int i = colStart; i <= colEnd; i++) { + result.add(matrix[rowStart][i]); } - else if (dir == 1) { - while (i < bottom) { - list.add(matrix[i++][j]); - count++; - } - dir++; - bottom--; - i--; - j--; + rowStart++; + for (int i = rowStart; i <= rowEnd; i++) { + result.add(matrix[i][colEnd]); } - else if (dir == 2) { - while (j >= left) { - list.add(matrix[i][j--]); - count++; + colEnd--; + if (rowStart <= rowEnd) { + for (int i = colEnd; i >= colStart; i--) { + result.add(matrix[rowEnd][i]); } - dir++; - i--; - j++; - left++; + rowEnd--; } - else if (dir == 3) { - while (i > top) { - list.add(matrix[i--][j]); - count++; + if (colStart <= colEnd) { + for (int i = rowEnd; i >= rowStart; i--) { + result.add(matrix[i][colStart]); } - dir = 0; - top++; - i++; - j++; + colStart++; } } - - return list; + return result; } } diff --git a/Medium/Split Array into Consecutive Subsequences.java b/Medium/Split Array into Consecutive Subsequences.java index f31de956..17425bd5 100644 --- a/Medium/Split Array into Consecutive Subsequences.java +++ b/Medium/Split Array into Consecutive Subsequences.java @@ -1,28 +1,33 @@ class Solution { public boolean isPossible(int[] nums) { - Map map = new HashMap<>(); - Map appendMap = new HashMap<>(); + PriorityQueue pq = new PriorityQueue<>((int[] o1, int[] o2) -> { + if (o1[1] == o2[1]) { + return (o1[1] - o1[0]) - (o2[1] - o2[0]); + } + return o1[1] - o2[1]; + }); for (int num : nums) { - map.put(num, map.getOrDefault(num, 0) + 1); - } - for (int i : nums) { - if (map.get(i) == 0) { - continue; - } - else if (appendMap.getOrDefault(i, 0) > 0) { - appendMap.put(i, appendMap.get(i) - 1); - appendMap.put(i + 1, appendMap.getOrDefault(i + 1, 0) + 1); + while (!pq.isEmpty() && pq.peek()[1] + 1 < num) { + if (!isValidSubsequence(pq.poll())) { + return false; + } } - else if (map.getOrDefault(i + 1, 0) > 0 && map.getOrDefault(i + 2, 0) > 0) { - map.put(i + 1, map.get(i + 1) - 1); - map.put(i + 2, map.get(i + 2) - 1); - appendMap.put(i + 3, appendMap.getOrDefault(i + 3, 0) + 1); + if (pq.isEmpty() || pq.peek()[1] == num) { + pq.add(new int[]{num, num}); + } else { + int[] subsequence = pq.poll(); + pq.add(new int[]{subsequence[0], num}); } - else { + } + while (!pq.isEmpty()) { + if (!isValidSubsequence(pq.poll())) { return false; } - map.put(i, map.get(i) - 1); } return true; } + + private boolean isValidSubsequence(int[] subsequence) { + return subsequence[1] - subsequence[0] + 1 >= 3; + } } diff --git a/Medium/Split Linked List in Parts.java b/Medium/Split Linked List in Parts.java new file mode 100644 index 00000000..2fdd787c --- /dev/null +++ b/Medium/Split Linked List in Parts.java @@ -0,0 +1,33 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode[] splitListToParts(ListNode head, int k) { + int length = 0; + ListNode curr = head; + while (curr != null) { + length++; + curr = curr.next; + } + ListNode[] splits = new ListNode[k]; + int elementsPerPart = length / k; + int partsWithExtra = length % k; + ListNode prev = null; + for (int i = 0; i < k && head != null; i++, partsWithExtra--) { + splits[i] = head; + for (int j = 0; j < elementsPerPart + (partsWithExtra > 0 ? 1 : 0); j++) { + prev = head; + head = head.next; + } + prev.next = null; + } + return splits; + } +} diff --git a/Medium/Split Linked List into Parts.java b/Medium/Split Linked List into Parts.java deleted file mode 100644 index 3fdff43c..00000000 --- a/Medium/Split Linked List into Parts.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode(int x) { val = x; } - * } - */ - -class Solution { - public ListNode[] splitListToParts(ListNode root, int k) { - int m = findLength(root); - ListNode temp = root; - - ListNode[] res = new ListNode[k]; - int size=m/k; - int l= m%k; - - for(int i=0;i1){ - temp=temp.next;j--; - } - if(size!=0 && l>0 && temp!=null){ temp=temp.next; l--;} - ListNode temp1=temp; - if(temp!=null) temp=temp.next; - if(temp1!=null) temp1.next=null; - res[i]=ans; - } - return res; - } - - private int findLength(ListNode root) { - if (root == null) return 0; - int l = 0; - while(root != null) { - l++; - root = root.next; - } - - return l; - } -} diff --git a/Medium/Split a String Into the Max Number of Unique Substrings.java b/Medium/Split a String Into the Max Number of Unique Substrings.java new file mode 100644 index 00000000..3e418df7 --- /dev/null +++ b/Medium/Split a String Into the Max Number of Unique Substrings.java @@ -0,0 +1,21 @@ +class Solution { + public int maxUniqueSplit(String s) { + Set seen = new HashSet<>(); + return backtrack(s, 0, seen); + } + + private int backtrack(String s, int idx, Set seen) { + if (idx == s.length()) { + return 0; + } + int count = 0; + for (int end = idx + 1; end <= s.length(); end++) { + String substring = s.substring(idx, end); + if (seen.add(substring)) { + count = Math.max(count, 1 + backtrack(s, end, seen)); + seen.remove(substring); + } + } + return count; + } +} diff --git a/Medium/Step-By-Step Directions From a Binary Tree Node to Another.java b/Medium/Step-By-Step Directions From a Binary Tree Node to Another.java new file mode 100644 index 00000000..59695899 --- /dev/null +++ b/Medium/Step-By-Step Directions From a Binary Tree Node to Another.java @@ -0,0 +1,44 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public String getDirections(TreeNode root, int startValue, int destValue) { + StringBuilder sourcePath = new StringBuilder(); + StringBuilder destinationPath = new StringBuilder(); + findPath(root, startValue, sourcePath); + findPath(root, destValue, destinationPath); + int idx = 0; + // Remove common prefix + while (idx < Math.min(sourcePath.length(), destinationPath.length()) && + sourcePath.charAt(sourcePath.length() - idx - 1) == destinationPath.charAt(destinationPath.length() - idx - 1)) { + idx++; + } + // Replace remaining sourcePath with 'U' and append remaining destinationPath + return "U".repeat(sourcePath.length() - idx) + destinationPath.reverse().toString().substring(idx); + } + + private boolean findPath(TreeNode root, int value, StringBuilder sb) { + if (root.val == value) { + return true; + } + if (root.left != null && findPath(root.left, value, sb)) { + sb.append("L"); + } + else if (root.right != null && findPath(root.right, value, sb)) { + sb.append("R"); + } + return sb.length() > 0; + } +} diff --git a/Medium/Stock Price Fluctuation.java b/Medium/Stock Price Fluctuation.java new file mode 100644 index 00000000..3b374efe --- /dev/null +++ b/Medium/Stock Price Fluctuation.java @@ -0,0 +1,49 @@ +class StockPrice { + Map map; + int mostRecentTimeStamp; + PriorityQueue minHeap; + PriorityQueue maxHeap; + public StockPrice() { + map = new HashMap<>(); + mostRecentTimeStamp = Integer.MIN_VALUE; + minHeap = new PriorityQueue<>(Comparator.comparingInt(a -> a[0])); + maxHeap = new PriorityQueue<>((a, b) -> b[0] - a[0]); + } + + public void update(int timestamp, int price) { + map.put(timestamp, price); + mostRecentTimeStamp = Math.max(mostRecentTimeStamp, timestamp); + minHeap.add(new int[]{price, timestamp}); + maxHeap.add(new int[]{price, timestamp}); + } + + public int current() { + return map.get(mostRecentTimeStamp); + } + + public int maximum() { + return getUpdatedValueFromHeap(maxHeap); + } + + public int minimum() { + return getUpdatedValueFromHeap(minHeap); + } + + private int getUpdatedValueFromHeap(PriorityQueue heap) { + int[] entry = heap.poll(); + while (entry[0] != map.get(entry[1])) { + entry = heap.poll(); + } + heap.add(entry); + return entry[0]; + } +} + +/** + * Your StockPrice object will be instantiated and called as such: + * StockPrice obj = new StockPrice(); + * obj.update(timestamp,price); + * int param_2 = obj.current(); + * int param_3 = obj.maximum(); + * int param_4 = obj.minimum(); + */ diff --git a/Medium/Stone Game II.java b/Medium/Stone Game II.java new file mode 100644 index 00000000..c56cbd43 --- /dev/null +++ b/Medium/Stone Game II.java @@ -0,0 +1,26 @@ +class Solution { + public int stoneGameII(int[] piles) { + Integer[][][] dp = new Integer[2][piles.length + 1][piles.length + 1]; + return helper(piles, dp, 0, 0, 1); + } + + private int helper(int[] piles, Integer[][][] dp, int p, int i, int m) { + if (i == piles.length) { + return 0; + } + if (dp[p][i][m] != null) { + return dp[p][i][m]; + } + int result = p == 1 ? 1000_000 : -1; + int s = 0; + for (int j = 1; j <= Math.min(2 * m, piles.length - i); j++) { + s += piles[i + j - 1]; + if (p == 0) { + result = Math.max(result, s + helper(piles, dp, 1, i + j, Math.max(m, j))); + } else { + result = Math.min(result, helper(piles, dp, 0, i + j, Math.max(m, j))); + } + } + return dp[p][i][m] = result; + } +} diff --git a/Medium/Strictly Palindromic Number.java b/Medium/Strictly Palindromic Number.java new file mode 100644 index 00000000..b2e27e3a --- /dev/null +++ b/Medium/Strictly Palindromic Number.java @@ -0,0 +1,32 @@ +class Solution { + public boolean isStrictlyPalindromic(int n) { + for (int i = 2; i <= n - 2; i++) { + if (!isPalindrome(convertToBase(n, i))) { + return false; + } + } + return true; + } + + private String convertToBase(int n, int base) { + StringBuilder sb = new StringBuilder(); + while (n > 0) { + sb.append(n % base); + n /= base; + } + return sb.reverse().toString(); + } + + private boolean isPalindrome(String s) { + int start = 0; + int end = s.length() - 1; + while (start < end) { + if (s.charAt(start) != s.charAt(end)) { + return false; + } + start++; + end--; + } + return true; + } +} diff --git a/Medium/String Compression III.java b/Medium/String Compression III.java new file mode 100644 index 00000000..03a6737c --- /dev/null +++ b/Medium/String Compression III.java @@ -0,0 +1,16 @@ +class Solution { + public String compressedString(String word) { + StringBuilder sb = new StringBuilder(); + int idx = 0; + while (idx < word.length()) { + char c = word.charAt(idx); + int count = 0; + while (idx < word.length() && word.charAt(idx) == c && count < 9) { + idx++; + count++; + } + sb.append(count).append(c); + } + return sb.toString(); + } +} diff --git a/Medium/String Compression.java b/Medium/String Compression.java new file mode 100644 index 00000000..060e655e --- /dev/null +++ b/Medium/String Compression.java @@ -0,0 +1,21 @@ +class Solution { + public int compress(char[] chars) { + int startIdx = 0; + for (int i = 0; i < chars.length;) { + char c = chars[i]; + int count = 0; + while (i < chars.length && chars[i] == c) { + count++; + i++; + } + chars[startIdx++] = c; + if (count > 1) { + String temp = String.valueOf(count); + for (char digit : temp.toCharArray()) { + chars[startIdx++] = digit; + } + } + } + return startIdx; + } +} diff --git a/Medium/String to Integer (atoi).java b/Medium/String to Integer (atoi).java new file mode 100644 index 00000000..e91cbec0 --- /dev/null +++ b/Medium/String to Integer (atoi).java @@ -0,0 +1,30 @@ +class Solution { + public int myAtoi(String s) { + int idx = 0; + int n = s.length(); + while (idx < n && s.charAt(idx) == ' ') { + idx++; + } + int sign = 1; + if (idx < n && (s.charAt(idx) == '-' || s.charAt(idx) == '+')) { + sign = s.charAt(idx) == '-' ? -1 : 1; + idx++; + } + if (idx == n || !Character.isDigit(s.charAt(idx))) { + return 0; + } + while (idx < n && s.charAt(idx) == '0') { + idx++; + } + int number = 0; + while (idx < n && Character.isDigit(s.charAt(idx))) { + int digit = Character.getNumericValue(s.charAt(idx)); + if ((number > Integer.MAX_VALUE / 10) || (number == Integer.MAX_VALUE / 10 && digit > Integer.MAX_VALUE % 10)) { + return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; + } + number = number * 10 + digit; + idx++; + } + return number * sign; + } +} diff --git a/Medium/String to Integer(atoi).java b/Medium/String to Integer(atoi).java deleted file mode 100644 index 9d2aaf81..00000000 --- a/Medium/String to Integer(atoi).java +++ /dev/null @@ -1,34 +0,0 @@ -class Solution { - public int myAtoi(String str) { - if (str.length() == 0) { - return 0; - } - - int idx = 0; - int n = str.length(); - int sign = 1; - while (idx < n && str.charAt(idx) == ' ') { - idx++; - } - - if (idx < n && (str.charAt(idx) == '-' || str.charAt(idx) == '+')) { - sign = str.charAt(idx) == '-' ? -1 : 1; - idx++; - } - - long num = 0; - while (idx < n && Character.isDigit(str.charAt(idx))) { - num = num * 10 + Character.getNumericValue(str.charAt(idx++)); - - if ((sign == 1 && num > Integer.MAX_VALUE) || (-num < Integer.MIN_VALUE)) { - return getOverflowValue(sign); - } - } - - return sign * (int) num; - } - - private int getOverflowValue(int sign) { - return sign == -1 ? Integer.MIN_VALUE : Integer.MAX_VALUE; - } -} diff --git a/Medium/Subarray Product Less Than K.java b/Medium/Subarray Product Less Than K.java index 68ba3e13..3f53dc87 100644 --- a/Medium/Subarray Product Less Than K.java +++ b/Medium/Subarray Product Less Than K.java @@ -1,18 +1,20 @@ class Solution { - public int numSubarrayProductLessThanK(int[] nums, int k) { - if (k <= 1) { - return 0; + public int numSubarrayProductLessThanK(int[] nums, int k) { + if (k <= 1) { + return 0; + } + int prod = 1; + int start = 0; + int end = 0; + int n = nums.length; + int result = 0; + while (end < n) { + prod *= nums[end++]; + while (start < end && prod >= k) { + prod /= nums[start++]; + } + result += end - start; + } + return result; } - int prod = 1; - int ans = 0; - int left = 0; - for (int right = 0; right < nums.length; right++) { - prod *= nums[right]; - while (prod >= k) { - prod /= nums[left++]; - } - ans += right - left + 1; - } - return ans; - } } diff --git a/Medium/Subdomain Visit Count.java b/Medium/Subdomain Visit Count.java new file mode 100644 index 00000000..f7900ef6 --- /dev/null +++ b/Medium/Subdomain Visit Count.java @@ -0,0 +1,22 @@ +class Solution { + public List subdomainVisits(String[] cpdomains) { + Map map = new HashMap<>(); + for (String cpdomain : cpdomains) { + int spaceIdx = cpdomain.indexOf(' '); + int count = Integer.parseInt(cpdomain.substring(0, spaceIdx)); + String[] subdomains = cpdomain.substring(spaceIdx + 1).split("\\."); + StringBuilder sb = new StringBuilder(); + for (int i = subdomains.length - 1; i >= 0; i--) { + sb.insert(0, subdomains[i]); + String currDomain = sb.toString(); + map.put(currDomain, map.getOrDefault(currDomain, 0L) + count); + sb.insert(0, "."); + } + } + List result = new ArrayList<>(); + for (String key : map.keySet()) { + result.add(map.get(key) + " " + key); + } + return result; + } +} diff --git a/Medium/Subsets.java b/Medium/Subsets.java index e86ccecd..3e0aba4d 100644 --- a/Medium/Subsets.java +++ b/Medium/Subsets.java @@ -1,19 +1,20 @@ class Solution { public List> subsets(int[] nums) { - List> list = new ArrayList<>(); - helper(nums, list, new ArrayList<>(), 0); - return list; + List> result = new ArrayList<>(); + helper(nums, 0, new ArrayList<>(), result); + return new ArrayList<>(result); } - - private void helper(int[] nums, List> list, List curr, int idx) { - list.add(new ArrayList<>(curr)); - if (idx >= nums.length) { + + private void helper(int[] nums, int currIdx, List currSubset, + List> result) { + result.add(new ArrayList<>(currSubset)); + if (currIdx >= nums.length) { return; } - for (int i = idx; i < nums.length; i++) { - curr.add(nums[i]); - helper(nums, list, curr, i + 1); - curr.remove(curr.size() - 1); + for (int i = currIdx; i < nums.length; i++) { + currSubset.add(nums[i]); + helper(nums, i + 1, currSubset, result); + currSubset.remove(currSubset.size() - 1); } } } diff --git a/Medium/Substrings That Begin and End With the Same Letter.java b/Medium/Substrings That Begin and End With the Same Letter.java new file mode 100644 index 00000000..62c93389 --- /dev/null +++ b/Medium/Substrings That Begin and End With the Same Letter.java @@ -0,0 +1,12 @@ +class Solution { + public long numberOfSubstrings(String s) { + int n = s.length(); + long result = 0; + long[] prefixCount = new long[26]; + for (int i = 0; i < n; i++) { + prefixCount[s.charAt(i) - 'a']++; + result += prefixCount[s.charAt(i) - 'a']; + } + return result; + } +} diff --git a/Medium/Successful Pairs of Spells and Potions.java b/Medium/Successful Pairs of Spells and Potions.java new file mode 100644 index 00000000..8a8e6886 --- /dev/null +++ b/Medium/Successful Pairs of Spells and Potions.java @@ -0,0 +1,26 @@ +class Solution { + public int[] successfulPairs(int[] spells, int[] potions, long success) { + Arrays.sort(potions); + int[] result = new int[spells.length]; + for (int i = 0; i < spells.length; i++) { + result[i] = findCountOfSuccessfulPotion(potions, success, (long) spells[i]); + } + return result; + } + + private int findCountOfSuccessfulPotion(int[] potions, long success, long spell) { + int left = 0; + int right = potions.length - 1; + int minIdx = Integer.MAX_VALUE; + while (left <= right) { + int mid = (left + right) / 2; + if (potions[mid] * spell >= success) { + minIdx = Math.min(minIdx, mid); + right = mid - 1; + } else { + left = mid + 1; + } + } + return minIdx == Integer.MAX_VALUE ? 0 : (potions.length - minIdx); + } +} diff --git a/Medium/Sum Multiples.java b/Medium/Sum Multiples.java new file mode 100644 index 00000000..59bfa012 --- /dev/null +++ b/Medium/Sum Multiples.java @@ -0,0 +1,7 @@ +class Solution { + public int sumOfMultiples(int n) { + return IntStream.rangeClosed(1, n) + .filter(value -> value % 3 == 0 || value % 5 == 0 || value % 7 == 0) + .sum(); + } +} diff --git a/Medium/Sum Root to Leaf Numbers.java b/Medium/Sum Root to Leaf Numbers.java index c24f21aa..0cad0868 100644 --- a/Medium/Sum Root to Leaf Numbers.java +++ b/Medium/Sum Root to Leaf Numbers.java @@ -14,23 +14,29 @@ * } */ class Solution { - public int sumNumbers(TreeNode root) { - int[] sum = {0}; - helper(root, sum, 0); - return sum[0]; - } - - private void helper(TreeNode node, int[] sum, int currVal) { - if (node == null) { - return; + public int sumNumbers(TreeNode root) { + if (root == null) { + return 0; + } + Queue queue = new LinkedList<>(); + queue.add(new NodeSumPair(root, 0)); + int totalSum = 0; + while (!queue.isEmpty()) { + NodeSumPair removed = queue.remove(); + TreeNode node = removed.node; + int currSum = removed.sum * 10 + node.val; + if (node.left == null && node.right == null) { + totalSum += currSum; + } + if (node.left != null) { + queue.add(new NodeSumPair(node.left, currSum)); + } + if (node.right != null) { + queue.add(new NodeSumPair(node.right, currSum)); + } + } + return totalSum; } - currVal = currVal * 10 + node.val; - if (node.left == null && node.right == null) { - sum[0] += currVal; - } - else { - helper(node.left, sum, currVal); - helper(node.right, sum, currVal); - } - } + + private static record NodeSumPair(TreeNode node, int sum) {} } diff --git a/Medium/Sum in a Matrix.java b/Medium/Sum in a Matrix.java new file mode 100644 index 00000000..0261f81b --- /dev/null +++ b/Medium/Sum in a Matrix.java @@ -0,0 +1,16 @@ +class Solution { + public int matrixSum(int[][] nums) { + for (int[] num : nums) { + Arrays.sort(num); + } + int score = 0; + for (int i = 0; i < nums[0].length; i++) { + int maxNum = 0; + for (int[] num : nums) { + maxNum = Math.max(maxNum, num[i]); + } + score += maxNum; + } + return score; + } +} diff --git a/Medium/Sum of Absolute Differences in a Sorted Array.java b/Medium/Sum of Absolute Differences in a Sorted Array.java new file mode 100644 index 00000000..de0e5920 --- /dev/null +++ b/Medium/Sum of Absolute Differences in a Sorted Array.java @@ -0,0 +1,22 @@ +class Solution { + public int[] getSumAbsoluteDifferences(int[] nums) { + int n = nums.length; + int[] answer = new int[n]; + int[] leftToRightSum = new int[n]; + int[] rightToLeftSum = new int[n]; + int currSum = 0; + for (int i = 0; i < n; i++) { + currSum += nums[i]; + leftToRightSum[i] = currSum; + } + currSum = 0; + for (int i = n - 1; i >= 0; i--) { + currSum += nums[i]; + rightToLeftSum[i] = currSum; + } + for (int i = 0; i < n; i++) { + answer[i] = (i == 0 ? 0 : i * nums[i] - leftToRightSum[i - 1]) + (i == n - 1 ? 0 : (rightToLeftSum[i + 1] - (n - 1 - i) * nums[i])); + } + return answer; + } +} diff --git a/Medium/Sum of Beauty of All Substrings.java b/Medium/Sum of Beauty of All Substrings.java new file mode 100644 index 00000000..17d57d14 --- /dev/null +++ b/Medium/Sum of Beauty of All Substrings.java @@ -0,0 +1,26 @@ +class Solution { + public int beautySum(String s) { + int sum = 0; + for (int i = 0; i < s.length(); i++) { + int[] charFrequency = new int[26]; + for (int j = i; j < s.length(); j++) { + charFrequency[s.charAt(j) - 'a']++; + sum += getBeauty(charFrequency); + } + } + return sum; + } + + private int getBeauty(int[] charFrequency) { + int min = Integer.MAX_VALUE ; + int max = Integer.MIN_VALUE; + for (int i = 0; i < 26; i++) { + if (charFrequency[i] == 0) { + continue; + } + min = Math.min(min, charFrequency[i]); + max = Math.max(max, charFrequency[i]); + } + return max - min; + } +} diff --git a/Medium/Sum of Even Numbers After Queries.java b/Medium/Sum of Even Numbers After Queries.java new file mode 100644 index 00000000..f8a3b043 --- /dev/null +++ b/Medium/Sum of Even Numbers After Queries.java @@ -0,0 +1,21 @@ +class Solution { + public int[] sumEvenAfterQueries(int[] nums, int[][] queries) { + int evenSum = 0; + for (int num : nums) { + evenSum += num % 2 == 0 ? num : 0; + } + int[] result = new int[nums.length]; + for (int i = 0; i < queries.length; i++) { + int idx = queries[i][1]; + if (nums[idx] % 2 == 0) { + evenSum -= nums[idx]; + } + nums[idx] += queries[i][0]; + if (nums[idx] % 2 == 0) { + evenSum += nums[idx]; + } + result[i] = evenSum; + } + return result; + } +} diff --git a/Medium/Sum of Nodes with Even-Valued Grandparent.java b/Medium/Sum of Nodes with Even-Valued Grandparent.java index d2519a60..7e113144 100644 --- a/Medium/Sum of Nodes with Even-Valued Grandparent.java +++ b/Medium/Sum of Nodes with Even-Valued Grandparent.java @@ -4,25 +4,38 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { - int sum; public int sumEvenGrandparent(TreeNode root) { - sum = 0; - helper(root, null, null); - return sum; - } - - private void helper(TreeNode root, TreeNode parent, TreeNode grandparent) { - if (root == null) { - return; + int sum = 0; + Queue queue = new LinkedList<>(); + queue.add(new TreeNode[]{root, null, null}); + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + TreeNode[] removed = queue.remove(); + TreeNode node = removed[0]; + TreeNode parent = removed[1]; + TreeNode grandParent = removed[2]; + if (grandParent != null && grandParent.val % 2 == 0) { + sum += node.val; + } + if (node.left != null) { + queue.add(new TreeNode[]{node.left, node, parent}); + } + if (node.right != null) { + queue.add(new TreeNode[]{node.right, node, parent}); + } + } } - if (grandparent != null && grandparent.val % 2 == 0) { - sum += root.val; - } - helper(root.left, root, parent); - helper(root.right, root, parent); + return sum; } } diff --git a/Medium/Sum of Numbers With Units Digit K.java b/Medium/Sum of Numbers With Units Digit K.java new file mode 100644 index 00000000..024b9dbf --- /dev/null +++ b/Medium/Sum of Numbers With Units Digit K.java @@ -0,0 +1,13 @@ +class Solution { + public int minimumNumbers(int num, int k) { + if (num == 0) { + return 0; + } + for (int i = 1; i * k <= num && i <= 10; i++) { + if (k * i % 10 == num % 10) { + return i; + } + } + return -1; + } +} diff --git a/Medium/Sum of Square Numbers.java b/Medium/Sum of Square Numbers.java new file mode 100644 index 00000000..13f138c2 --- /dev/null +++ b/Medium/Sum of Square Numbers.java @@ -0,0 +1,18 @@ +class Solution { + public boolean judgeSquareSum(int c) { + long left = 0; + long right = (long) Math.sqrt(c); + while (left <= right) { + long sum = left * left + right * right; + if (sum == c) { + return true; + } + if (sum > c) { + right--; + } else { + left++; + } + } + return false; + } +} diff --git a/Medium/Sum of Subarray Minimums.java b/Medium/Sum of Subarray Minimums.java new file mode 100644 index 00000000..942f0c91 --- /dev/null +++ b/Medium/Sum of Subarray Minimums.java @@ -0,0 +1,20 @@ +class Solution { + + private final static int MOD = 1000_000_007; + + public int sumSubarrayMins(int[] arr) { + Stack stack = new Stack<>(); + long sum = 0; + for (int i = 0; i <= arr.length; i++) { + while (!stack.isEmpty() && (i == arr.length || arr[stack.peek()] >= arr[i])) { + int minValue = stack.pop(); + int countOnLeft = stack.empty() ? -1 : stack.peek(); + int countOnRight = i; + long totalCount = (minValue - countOnLeft) * (countOnRight - minValue) % MOD; + sum = (sum + (totalCount * arr[minValue])) % MOD; + } + stack.push(i); + } + return (int) (sum); + } +} diff --git a/Medium/Summary Ranges.java b/Medium/Summary Ranges.java deleted file mode 100644 index 340b0f30..00000000 --- a/Medium/Summary Ranges.java +++ /dev/null @@ -1,18 +0,0 @@ -class Solution { - public List summaryRanges(int[] nums) { - List list = new ArrayList<>(); - int idx = 0; - int n = nums.length; - while (idx < n) { - int start = nums[idx]; - int prev = start; - idx++; - while (idx < n && nums[idx] - prev == 1) { - prev = nums[idx]; - idx++; - } - list.add(start == prev ? String.valueOf(start) : String.valueOf(start + "->" + prev)); - } - return list; - } -} diff --git a/Medium/Swap For Longest Repeated Character Substring.java b/Medium/Swap For Longest Repeated Character Substring.java index d09edb22..fd71081e 100644 --- a/Medium/Swap For Longest Repeated Character Substring.java +++ b/Medium/Swap For Longest Repeated Character Substring.java @@ -1,29 +1,40 @@ class Solution { public int maxRepOpt1(String text) { - int[] count = new int[26]; + int[] frequency = new int[26]; for (char c : text.toCharArray()) { - count[c - 'a']++; + frequency[c - 'a']++; } - int maxCount = 0; - int i = 0; - while (i < text.length()) { + int maxRepeatingLength = 0; + for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); - int curr = i; - int currCount = 0; + int j = i; + int count = 0; int diff = 0; - // To skip the same characters before we make a swap - int swapPoint = i; - while (curr < text.length() && (text.charAt(curr) == c || diff == 0) && currCount < count[c - 'a']) { - if (text.charAt(curr) != c) { + while (j < text.length() && (c == text.charAt(j) || diff == 0) && count < frequency[c - 'a']) { + if (c != text.charAt(j)) { diff++; - swapPoint = curr - 1; + i = j - 1; } - currCount++; - curr++; + count++; + j++; } - maxCount = Math.max(maxCount, currCount); - i = swapPoint + 1; + maxRepeatingLength = Math.max(maxRepeatingLength, count); } - return maxCount; + for (int i = text.length() - 1; i >= 0; i--) { + char c = text.charAt(i); + int count = 0; + int diff = 0; + int j = i; + while (j >= 0 && (c == text.charAt(j) || diff == 0) && count < frequency[c - 'a']) { + if (c != text.charAt(j)) { + diff++; + i = j + 1; + } + count++; + j--; + } + maxRepeatingLength = Math.max(maxRepeatingLength, count); + } + return maxRepeatingLength; } } diff --git a/Medium/Swap Nodes in Pair.java b/Medium/Swap Nodes in Pair.java deleted file mode 100644 index 478438f6..00000000 --- a/Medium/Swap Nodes in Pair.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Definition for singly-linked list. - * public class ListNode { - * int val; - * ListNode next; - * ListNode(int x) { val = x; } - * } - */ -class Solution { - public ListNode swapPairs(ListNode head) { - if (head == null || head.next == null) { - return head; - } - ListNode next = head.next; - head.next = swapPairs(head.next.next); - next.next = head; - return next; - } - - private ListNode reverseHeadPair(ListNode head) { - if (head == null || head.next == null) { - return head; - } - ListNode next = head.next; - head.next = reverseHeadPair(head.next.next); - next.next = head; - return next; - } -} diff --git a/Medium/Swap Nodes in Pairs.java b/Medium/Swap Nodes in Pairs.java new file mode 100644 index 00000000..505f7af0 --- /dev/null +++ b/Medium/Swap Nodes in Pairs.java @@ -0,0 +1,31 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode swapPairs(ListNode head) { + ListNode curr = head; + ListNode prev = null; + while (curr != null && curr.next != null) { + ListNode nextNode = curr.next; + ListNode nextToNext = curr.next.next; + if (prev == null) { + head = nextNode; + } + if (prev != null) { + prev.next = nextNode; + } + nextNode.next = curr; + curr.next = nextToNext; + prev = curr; + curr = nextToNext; + } + return head; + } +} diff --git a/Medium/Swapping Nodes in a Linked List.java b/Medium/Swapping Nodes in a Linked List.java new file mode 100644 index 00000000..8fdf72f4 --- /dev/null +++ b/Medium/Swapping Nodes in a Linked List.java @@ -0,0 +1,53 @@ +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode() {} + * ListNode(int val) { this.val = val; } + * ListNode(int val, ListNode next) { this.val = val; this.next = next; } + * } + */ +class Solution { + public ListNode swapNodes(ListNode head, int k) { + int listLength = 0; + ListNode curr = head; + while (curr != null) { + listLength++; + curr = curr.next; + } + ListNode startPrev = null; + ListNode start = head; + ListNode endPrev = null; + ListNode end = head; + int count = k - 1; + while (count > 0) { + startPrev = start; + start = start.next; + count--; + } + count = listLength - k; + while (count > 0) { + endPrev = end; + end = end.next; + count--; + } + if (startPrev != null) { + startPrev.next = end; + } + if (endPrev != null) { + endPrev.next = start; + } + ListNode temp = start.next; + start.next = end.next; + end.next = temp; + // Updating head pointers if required + if (k == 1) { + head = end; + } + if (k == listLength) { + head = start; + } + return head; + } +} diff --git a/Medium/Synonymous Sentences.java b/Medium/Synonymous Sentences.java new file mode 100644 index 00000000..6de8d907 --- /dev/null +++ b/Medium/Synonymous Sentences.java @@ -0,0 +1,27 @@ +class Solution { + public List generateSentences(List> synonyms, String text) { + Map> synonymMapping = new HashMap<>(); + for (List synonym : synonyms) { + synonymMapping.computeIfAbsent(synonym.get(0), k -> new ArrayList<>()).add(synonym.get(1)); + synonymMapping.computeIfAbsent(synonym.get(1), k -> new ArrayList<>()).add(synonym.get(0)); + } + Set result = new TreeSet<>(); + Queue queue = new LinkedList<>(); + queue.add(text); + while (!queue.isEmpty()) { + String removed = queue.remove(); + result.add(removed); + String[] words = removed.split("\\s+"); + for (int i = 0; i < words.length; i++) { + for (String synonym : synonymMapping.getOrDefault(words[i], new ArrayList<>())) { + words[i] = synonym; + String updatedSentence = String.join(" ", words); + if (!result.contains(updatedSentence)) { + queue.add(updatedSentence); + } + } + } + } + return new ArrayList<>(result); + } +} diff --git a/Medium/Take K of Each Character From Left and Right.java b/Medium/Take K of Each Character From Left and Right.java new file mode 100644 index 00000000..4b878ce0 --- /dev/null +++ b/Medium/Take K of Each Character From Left and Right.java @@ -0,0 +1,27 @@ +class Solution { + public int takeCharacters(String s, int k) { + int[] counter = new int[3]; + int n = s.length(); + for (char c : s.toCharArray()) { + counter[c - 'a']++; + } + for (int i = 0; i < 3; i++) { + if (counter[i] < k) { + return -1; + } + } + int[] window = new int[3]; + int left = 0; + int maxWindow = 0; + for (int right = 0; right < n; right++) { + window[s.charAt(right) - 'a']++; + while (left <= right && + (counter[0] - window[0] < k || counter[1] - window[1] < k || counter[2] - window[2] < k)) { + window[s.charAt(left) - 'a']--; + left++; + } + maxWindow = Math.max(maxWindow, right - left + 1); + } + return n - maxWindow; + } +} diff --git a/Medium/Task Scheduler.java b/Medium/Task Scheduler.java index 5d535437..0023aa9d 100644 --- a/Medium/Task Scheduler.java +++ b/Medium/Task Scheduler.java @@ -1,16 +1,30 @@ class Solution { - public int leastInterval(char[] tasks, int n) { - int[] counter = new int[26]; - for (char task : tasks) { - counter[task - 'A']++; + public int leastInterval(char[] tasks, int n) { + Map map = new HashMap<>(); + for (char c : tasks) { + map.put(c, map.getOrDefault(c, 0) + 1); + } + PriorityQueue pq = new PriorityQueue<>((a, b) -> b - a); + pq.addAll(map.values()); + int cycles = 0; + while (!pq.isEmpty()) { + List temp = new ArrayList<>(); + // Wait for one cooldown period and process one occurrence of all remaining tasks + for (int i = 0; i < n + 1; i++) { + if (!pq.isEmpty()) { + temp.add(pq.remove()); + } + } + // If task has more occurrences left then add it back to heap + for (int task : temp) { + if (task > 1) { + pq.add(task - 1); + } + } + // If heap is empty that means we finished all tasks and don't need to wait for + // the whole cooldown to finish else add one complete cooldown period + cycles += pq.isEmpty() ? temp.size() : n + 1; + } + return cycles; } - Arrays.sort(counter); - int maxFrequency = counter[25]; - int idleTime = (maxFrequency - 1) * n; - for (int i = counter.length - 2; i >= 0 && idleTime > 0; i--) { - idleTime -= Math.min(maxFrequency - 1, counter[i]); - } - idleTime = Math.max(0, idleTime); - return idleTime + tasks.length; - } } diff --git a/Medium/Teemo Attacking.java b/Medium/Teemo Attacking.java deleted file mode 100644 index f91db3db..00000000 --- a/Medium/Teemo Attacking.java +++ /dev/null @@ -1,22 +0,0 @@ -class Solution { - public int findPoisonedDuration(int[] timeSeries, int duration) { - if (timeSeries.length == 0 || duration <= 0) { - return 0; - } - int totalTimePoisened = 0; - int currPoisenedTime = 0; - int n = timeSeries.length; - for (int i = 0; i < n; i++) { - if (currPoisenedTime > 0) { - if (currPoisenedTime <= timeSeries[i]) { - totalTimePoisened += duration; - } - else { - totalTimePoisened += timeSeries[i] - timeSeries[i - 1]; - } - } - currPoisenedTime = timeSeries[i] + duration; - } - return totalTimePoisened + (currPoisenedTime - timeSeries[n - 1]); - } -} diff --git a/Medium/Ternary Expression Parser.java b/Medium/Ternary Expression Parser.java index c0079881..6798336d 100644 --- a/Medium/Ternary Expression Parser.java +++ b/Medium/Ternary Expression Parser.java @@ -1,23 +1,19 @@ class Solution { - public String parseTernary(String expression) { - if (expression == null || expression.length() == 0) { - return ""; + public String parseTernary(String expression) { + Stack stack = new Stack<>(); + int idx = expression.length() - 1; + while (idx >= 0) { + char c = expression.charAt(idx); + if (c >= '0' && c <= '9' || c == 'T' || c == 'F') { + stack.push(c); + } else if (c == '?') { + char trueValue = stack.pop(); + char falseValue = stack.pop(); + stack.push(expression.charAt(idx - 1) == 'T' ? trueValue : falseValue); + idx--; + } + idx--; + } + return String.valueOf(stack.pop()); } - Deque stack = new LinkedList<>(); - int n = expression.length(); - for (int i = n - 1; i >= 0; i--) { - char c = expression.charAt(i); - if (!stack.isEmpty() && stack.peek() == '?') { - stack.pop(); // Pop ? - char first = stack.pop(); - stack.pop(); // Pop : - char second = stack.pop(); - stack.push(c == 'T' ? first : second); - } - else { - stack.push(c); - } - } - return String.valueOf(stack.peek()); - } } diff --git a/Medium/The Earliest Moment When Everyone Become Friends.java b/Medium/The Earliest Moment When Everyone Become Friends.java index 739711d6..8de3e818 100644 --- a/Medium/The Earliest Moment When Everyone Become Friends.java +++ b/Medium/The Earliest Moment When Everyone Become Friends.java @@ -1,47 +1,41 @@ class Solution { - public int earliestAcq(int[][] logs, int N) { - Arrays.sort(logs, Comparator.comparingInt(o -> o[0])); - Map> map = new HashMap<>(); - + public int earliestAcq(int[][] logs, int n) { + Arrays.sort(logs, Comparator.comparingInt(a -> a[0])); + UnionFind uf = new UnionFind(n); for (int[] log : logs) { - boolean[] allDone = {false}; - map.computeIfAbsent(log[1], k -> new HashSet<>()).add(log[2]); - dfs(map, log[1], log[2], allDone, N); - - map.computeIfAbsent(log[2], k -> new HashSet<>()).add(log[1]); - dfs(map, log[2], log[1], allDone, N); - - - if (allDone[0]) { + uf.union(log[1], log[2]); + if (uf.count == 1) { return log[0]; } } - return -1; } - private void dfs(Map> map, int f1, int f2, boolean[] allDone, int N) { - Set visited = new HashSet<>(); - Queue queue = new LinkedList<>(); - queue.add(f1); - visited.add(f1); + static class UnionFind { + private final int[] parent; + private int count; - while (!queue.isEmpty()) { - int removed = queue.poll(); - Iterator iterator = map.getOrDefault(removed, new HashSet<>()).iterator(); - while (iterator.hasNext()) { - int friend = iterator.next(); - if (!visited.contains(friend)) { - queue.add(friend); - map.computeIfAbsent(friend, k -> new HashSet<>()).add(f2); - map.computeIfAbsent(f2, k -> new HashSet<>()).add(friend); + public UnionFind(int n) { + parent = new int[n]; + count = n; + for (int i = 0; i < n; i++) { + parent[i] = i; + } + } - if (map.get(f2).size() == N || map.get(friend).size() == N) { - allDone[0] = true; - } + public int find(int node) { + if (parent[node] != node) { + parent[node] = find(parent[node]); + } + return parent[node]; + } - visited.add(friend); - } + public void union(int x, int y) { + int rootX = find(x); + int rootY = find(y); + if (rootX != rootY) { + parent[rootX] = rootY; + count--; } } } diff --git a/Medium/The Number of Beautiful Subsets.java b/Medium/The Number of Beautiful Subsets.java new file mode 100644 index 00000000..7057a18d --- /dev/null +++ b/Medium/The Number of Beautiful Subsets.java @@ -0,0 +1,20 @@ +class Solution { + public int beautifulSubsets(int[] nums, int k) { + Map freqMap = new HashMap<>(); + Arrays.sort(nums); + return countBeautifulSubsets(nums, k, freqMap, 0) - 1; + } + + private int countBeautifulSubsets(int[] nums, int k, Map freqMap, int idx) { + if (idx == nums.length) { + return 1; + } + int count = countBeautifulSubsets(nums, k, freqMap, idx + 1); + if (freqMap.getOrDefault(nums[idx] - k, 0) == 0) { + freqMap.put(nums[idx], freqMap.getOrDefault(nums[idx], 0) + 1); + count += countBeautifulSubsets(nums, k, freqMap, idx + 1); + freqMap.put(nums[idx], freqMap.getOrDefault(nums[idx], 0) - 1); + } + return count; + } +} diff --git a/Medium/The Number of Full Rounds You Have Played.java b/Medium/The Number of Full Rounds You Have Played.java new file mode 100644 index 00000000..a265d7f7 --- /dev/null +++ b/Medium/The Number of Full Rounds You Have Played.java @@ -0,0 +1,24 @@ +class Solution { + public int numberOfRounds(String startTime, String finishTime) { + int startMinutes = toMinutes(startTime); + int finishMinutes = toMinutes(finishTime); + int roundedStart = toNextQuarter(startMinutes); + int roundedFinish = toPreviousQuarter(finishMinutes); + if (startMinutes < finishMinutes) { + return Math.max(0, (roundedFinish - roundedStart) / 15); + } + return (24 * 60 - roundedStart + roundedFinish) / 15; + } + + public static int toMinutes(String s) { + return Integer.parseInt(s.substring(0, 2)) * 60 + Integer.parseInt(s.substring(3, 5)); + } + + public static int toNextQuarter(int time) { + return ((time + 14) / 15) * 15; + } + + public static int toPreviousQuarter(int time) { + return (time / 15) * 15; + } +} diff --git a/Medium/The Number of Weak Characters in the Game.java b/Medium/The Number of Weak Characters in the Game.java new file mode 100644 index 00000000..18607097 --- /dev/null +++ b/Medium/The Number of Weak Characters in the Game.java @@ -0,0 +1,26 @@ +class Solution { + public int numberOfWeakCharacters(int[][] properties) { + int maxAttackValue = 0; + for (int[] property : properties) { + maxAttackValue = Math.max(maxAttackValue, property[0]); + } + int maxDefense[] = new int[maxAttackValue + 2]; + for (int[] property : properties) { + int attack = property[0]; + int defense = property[1]; + maxDefense[attack] = Math.max(maxDefense[attack], defense); + } + for (int i = maxAttackValue - 1; i >= 0; i--) { + maxDefense[i] = Math.max(maxDefense[i], maxDefense[i + 1]); + } + int count = 0; + for (int[] property : properties) { + int attack = property[0]; + int defense = property[1]; + if (defense < maxDefense[attack + 1]) { + count++; + } + } + return count; + } +} diff --git a/Medium/The Number of the Smallest Unoccupied Chair.java b/Medium/The Number of the Smallest Unoccupied Chair.java new file mode 100644 index 00000000..6bd41ad2 --- /dev/null +++ b/Medium/The Number of the Smallest Unoccupied Chair.java @@ -0,0 +1,35 @@ +class Solution { + public int smallestChair(int[][] times, int targetFriend) { + PriorityQueue pq = new PriorityQueue<>((o1, o2) -> { + int c = o1[0] - o2[0]; + if (c == 0) { + return o1[1] - o2[1]; + } + return c; + }); + for (int i = 0; i < times.length; i++) { + pq.add(new int[]{times[i][0], times[i][1], i}); + } + PriorityQueue occupiedChairs = new PriorityQueue<>(Comparator.comparingInt(o -> o[0])); + PriorityQueue emptyChairs = new PriorityQueue<>(); + int currChair = 0; + while (!pq.isEmpty()) { + int[] time = pq.poll(); + while (!occupiedChairs.isEmpty() && occupiedChairs.peek()[0] <= time[0]) { + int[] chair = occupiedChairs.poll(); + emptyChairs.add(chair[1]); + } + if (time[2] == targetFriend) { + return emptyChairs.isEmpty() ? currChair : emptyChairs.poll(); + } + if (emptyChairs.isEmpty()) { + occupiedChairs.add(new int[]{time[1], currChair}); + currChair++; + } else { + int chair = emptyChairs.poll(); + occupiedChairs.add(new int[]{time[1], chair}); + } + } + return -1; + } +} diff --git a/Medium/The k-th Lexicographical String of All Happy Strings of Length n.java b/Medium/The k-th Lexicographical String of All Happy Strings of Length n.java new file mode 100644 index 00000000..413b67d5 --- /dev/null +++ b/Medium/The k-th Lexicographical String of All Happy Strings of Length n.java @@ -0,0 +1,28 @@ +class Solution { + private static final char[] CHARS = {'a', 'b', 'c'}; + + public String getHappyString(int n, int k) { + Set set = new HashSet<>(); + backtrack(set, new StringBuilder(), n); + if (set.size() < k) { + return ""; + } + List list = new ArrayList<>(set); + Collections.sort(list); + return list.get(k - 1); + } + + private void backtrack(Set set, StringBuilder sb, int n) { + if (sb.length() == n) { + set.add(sb.toString()); + return; + } + for (char c : CHARS) { + if (sb.isEmpty() || sb.charAt(sb.length() - 1) != c) { + sb.append(c); + backtrack(set, sb, n); + sb.deleteCharAt(sb.length() - 1); + } + } + } +} diff --git a/Medium/The kth Factor of n.java b/Medium/The kth Factor of n.java new file mode 100644 index 00000000..046b3293 --- /dev/null +++ b/Medium/The kth Factor of n.java @@ -0,0 +1,10 @@ +class Solution { + public int kthFactor(int n, int k) { + for (int i = 1; i <= n / 2; i++) { + if (n % i == 0 && --k == 0) { + return i; + } + } + return k == 1 ? n : -1; + } +} diff --git a/Medium/Throne Inheritence.java b/Medium/Throne Inheritence.java new file mode 100644 index 00000000..49b2ed0c --- /dev/null +++ b/Medium/Throne Inheritence.java @@ -0,0 +1,42 @@ +class ThroneInheritance { + Map> family; + Set deadPeople; + String king; + public ThroneInheritance(String kingName) { + this.king = kingName; + family = new HashMap<>(); + family.put(kingName, new ArrayList<>()); + deadPeople = new HashSet<>(); + } + + public void birth(String parentName, String childName) { + family.computeIfAbsent(parentName, k -> new ArrayList<>()).add(childName); + } + + public void death(String name) { + deadPeople.add(name); + } + + public List getInheritanceOrder() { + List inheritenceOrder = new ArrayList<>(); + findInheritenceRecursively(king, inheritenceOrder); + return inheritenceOrder; + } + + private void findInheritenceRecursively(String currPerson, List inheritenceOrder) { + if (!deadPeople.contains(currPerson)) { + inheritenceOrder.add(currPerson); + } + for (String children : family.getOrDefault(currPerson, new ArrayList<>())) { + findInheritenceRecursively(children, inheritenceOrder); + } + } +} + +/** + * Your ThroneInheritance object will be instantiated and called as such: + * ThroneInheritance obj = new ThroneInheritance(kingName); + * obj.birth(parentName,childName); + * obj.death(name); + * List param_3 = obj.getInheritanceOrder(); + */ diff --git a/Medium/Time Based Key-Value Store.java b/Medium/Time Based Key-Value Store.java index d89b9c65..7433689e 100644 --- a/Medium/Time Based Key-Value Store.java +++ b/Medium/Time Based Key-Value Store.java @@ -1,29 +1,43 @@ class TimeMap { - /** Initialize your data structure here. */ - Map> map; + private Map> map; + public TimeMap() { - map = new HashMap<>(); + this.map = new HashMap<>(); } public void set(String key, String value, int timestamp) { - if (!map.containsKey(key)) { - TreeMap tMap = new TreeMap<>(); - map.put(key, tMap); - } - map.get(key).put(timestamp, value); + this.map.computeIfAbsent(key, k -> new ArrayList<>()).add(new TimeStampValuePair(timestamp, value)); } public String get(String key, int timestamp) { - if (!map.containsKey(key)) { + if (!this.map.containsKey(key)) { return ""; } - TreeMap tMap = map.get(key); - Integer lower = tMap.floorKey(timestamp); - if (lower == null) { - return ""; + List pairs = this.map.get(key); + int left = 0; + int right = pairs.size() - 1; + int maxIdx = -1; + while (left <= right) { + int mid = (left + right) / 2; + if (pairs.get(mid).timestamp <= timestamp) { + maxIdx = mid; + left = mid + 1; + } else { + right = mid - 1; + } + } + return maxIdx == -1 ? "" : pairs.get(maxIdx).value; + } + + private class TimeStampValuePair { + int timestamp; + String value; + + public TimeStampValuePair(int timestamp, String value) { + this.timestamp = timestamp; + this.value = value; } - return tMap.get(lower); } } diff --git a/Medium/Time Needed to Inform All Employees.java b/Medium/Time Needed to Inform All Employees.java index 901f53b5..f8cc21ac 100644 --- a/Medium/Time Needed to Inform All Employees.java +++ b/Medium/Time Needed to Inform All Employees.java @@ -1,23 +1,24 @@ class Solution { - public int numOfMinutes(int n, int headID, int[] manager, int[] informTime) { - Map> organization = new HashMap<>(); - for (int i = 0; i < manager.length; i++) { - if (manager[i] != -1) { - organization.computeIfAbsent(manager[i], k -> new ArrayList<>()).add(i); - } + public int numOfMinutes(int n, int headID, int[] manager, int[] informTime) { + Map> organization = new HashMap<>(); + for (int i = 0; i < manager.length; i++) { + if (manager[i] == -1) { + continue; + } + organization.computeIfAbsent(manager[i], k -> new ArrayList<>()).add(i); + } + int maxTime = 0; + Queue queue = new LinkedList<>(); + queue.add(new int[]{headID, 0}); + while (!queue.isEmpty()) { + int[] removed = queue.remove(); + int currManager = removed[0]; + int timeElapsed = removed[1]; + maxTime = Math.max(maxTime, timeElapsed); + for (Integer employee : organization.getOrDefault(currManager, new ArrayList<>())) { + queue.add(new int[]{employee, timeElapsed + informTime[currManager]}); + } + } + return maxTime; } - int totalTime = 0; - Queue queue = new LinkedList<>(); - queue.add(new int[]{headID, 0}); - while (!queue.isEmpty()) { - int[] removed = queue.remove(); - int id = removed[0]; - int time = removed[1]; - totalTime = Math.max(totalTime, time); - for (int associate : organization.getOrDefault(id, new ArrayList<>())) { - queue.add(new int[]{associate, time + informTime[id]}); - } - } - return totalTime; - } } diff --git a/Medium/Time Needed to Rearrange a Binary String.java b/Medium/Time Needed to Rearrange a Binary String.java new file mode 100644 index 00000000..f9c4dcf5 --- /dev/null +++ b/Medium/Time Needed to Rearrange a Binary String.java @@ -0,0 +1,13 @@ +class Solution { + public int secondsToRemoveOccurrences(String s) { + int time = 0; + int zeros = 0; + for (int i = 0; i < s.length(); i++) { + zeros += s.charAt(i) == '0' ? 1 : 0; + if (s.charAt(i) == '1' && zeros > 0) { + time = Math.max(time + 1, zeros); + } + } + return time; + } +} diff --git a/Medium/Top K Frequent Elements.java b/Medium/Top K Frequent Elements.java index f3f6ae2d..ffb13529 100644 --- a/Medium/Top K Frequent Elements.java +++ b/Medium/Top K Frequent Elements.java @@ -4,21 +4,22 @@ public int[] topKFrequent(int[] nums, int k) { for (int num : nums) { map.put(num, map.getOrDefault(num, 0) + 1); } - PriorityQueue pq = new PriorityQueue<>(new Comparator(){ - public int compare(Integer p1, Integer p2) { - return map.get(p1) - map.get(p2); - } - }); + Map> frequencyToValueMap = new HashMap<>(); for (Integer key : map.keySet()) { - pq.add(key); - if (pq.size() > k) { - pq.poll(); - } + frequencyToValueMap.computeIfAbsent(map.get(key), j -> new ArrayList<>()).add(key); } - int[] ans = new int[k]; - for (int i = 0; i < k; i++) { - ans[i] = pq.poll(); + List result = new ArrayList<>(); + for (int i = nums.length; i >= 0 && result.size() < k; i--) { + List values = frequencyToValueMap.getOrDefault(i, new ArrayList<>()); + if (result.size() + values.size() <= k) { + result.addAll(values); + } else { + int idx = 0; + while (result.size() < k) { + result.add(values.get(idx++)); + } + } } - return ans; + return result.stream().mapToInt(i -> i).toArray(); } } diff --git a/Medium/Top K Frequent Words.java b/Medium/Top K Frequent Words.java index 50a3911f..7f1c4f9f 100644 --- a/Medium/Top K Frequent Words.java +++ b/Medium/Top K Frequent Words.java @@ -1,23 +1,29 @@ class Solution { public List topKFrequent(String[] words, int k) { - Map map = new HashMap<>(); + Map wordFrequency = new HashMap<>(); + Map> frequencyToWord = new HashMap<>(); + int maxFrequency = 0; for (String word : words) { - map.put(word, map.getOrDefault(word, 0) + 1); + if (!wordFrequency.containsKey(word)) { + wordFrequency.put(word, 1); + frequencyToWord.computeIfAbsent(1, j -> new HashSet<>()).add(word); + } else { + int oldFrequency = wordFrequency.get(word); + int newFrequency = oldFrequency + 1; + wordFrequency.put(word, newFrequency); + frequencyToWord.get(oldFrequency).remove(word); + frequencyToWord.computeIfAbsent(newFrequency, j -> new HashSet<>()).add(word); + } + maxFrequency = Math.max(maxFrequency, wordFrequency.get(word)); } - PriorityQueue pq = new PriorityQueue<>(new Comparator(){ - public int compare(String s1, String s2) { - int c = map.get(s2) - map.get(s1); - if (c != 0) { - return c; - } - return s1.compareTo(s2); + List result = new ArrayList<>(); + for (int i = maxFrequency; i > 0 && result.size() < k; i--) { + List currFreqWords = new ArrayList<>(frequencyToWord.get(i)); + Collections.sort(currFreqWords); + for (int j = 0; j < currFreqWords.size() && result.size() < k; j++) { + result.add(currFreqWords.get(j)); } - }); - pq.addAll(map.keySet()); - List ans = new ArrayList<>(); - while (!pq.isEmpty() && k-- > 0) { - ans.add(pq.poll()); } - return ans; + return result; } } diff --git a/Medium/Total Characters in String After Transformations I.java b/Medium/Total Characters in String After Transformations I.java new file mode 100644 index 00000000..3751ab7e --- /dev/null +++ b/Medium/Total Characters in String After Transformations I.java @@ -0,0 +1,25 @@ +class Solution { + + private static final int MOD = 1000_0000_07; + + public int lengthAfterTransformations(String s, int t) { + int[] frequency = new int[26]; + for (char c : s.toCharArray()) { + frequency[c - 'a']++; + } + for (int round = 0; round < t; round++) { + int[] next = new int[26]; + next[0] = frequency[25]; // Transformation from 'z' + next[1] = (frequency[25] + frequency[0]) % MOD; // Transformation from either 'z' or 'a' + for (int i = 2; i < 26; i++) { + next[i] = frequency[i - 1]; // Transformation for next character + } + frequency = next; + } + int result = 0; + for (int i = 0; i < 26; i++) { + result = (result + frequency[i]) % MOD; + } + return result; + } +} diff --git a/Medium/Total Cost to Hire K Workers.java b/Medium/Total Cost to Hire K Workers.java new file mode 100644 index 00000000..c5708a4b --- /dev/null +++ b/Medium/Total Cost to Hire K Workers.java @@ -0,0 +1,29 @@ +class Solution { + public long totalCost(int[] costs, int k, int candidates) { + PriorityQueue headWorkers = new PriorityQueue<>(); + PriorityQueue tailWorkers = new PriorityQueue<>(); + for (int i = 0; i < candidates; i++) { + headWorkers.add(costs[i]); + } + for (int i = Math.max(candidates, costs.length - candidates); i < costs.length; i++) { + tailWorkers.add(costs[i]); + } + int headIdx = candidates; + int tailIdx = costs.length - candidates - 1; + long result = 0; + for (int i = 0; i < k; i++) { + if (tailWorkers.isEmpty() || (!headWorkers.isEmpty() && headWorkers.peek() <= tailWorkers.peek())) { + result += headWorkers.poll(); + if (headIdx <= tailIdx) { + headWorkers.add(costs[headIdx++]); + } + } else { + result += tailWorkers.poll(); + if (headIdx <= tailIdx) { + tailWorkers.add(costs[tailIdx--]); + } + } + } + return result; + } +} diff --git a/Medium/Tree Diameter.java b/Medium/Tree Diameter.java new file mode 100644 index 00000000..87d5eab9 --- /dev/null +++ b/Medium/Tree Diameter.java @@ -0,0 +1,39 @@ +class Solution { + public int treeDiameter(int[][] edges) { + int n = edges.length; + List> graph = new ArrayList<>(); + boolean[] visited = new boolean[n + 1]; + for (int i = 0; i < n + 1; i++) { + graph.add(new HashSet<>()); + } + for (int[] edge : edges) { + int nodeOne = edge[0]; + int nodeTwo = edge[1]; + graph.get(nodeOne).add(nodeTwo); + graph.get(nodeTwo).add(nodeOne); + } + int[] diameter = {0}; + dfs(0, visited, graph, diameter); + return diameter[0]; + } + + private int dfs(int node, boolean[] visited, List> graph, int[] diameter) { + int highestDistance = 0; + int secondHighestDistance = 0; + visited[node] = true; + for (Integer conn : graph.get(node)) { + int distance = 0; + if (!visited[conn]) { + distance = 1 + dfs(conn, visited, graph, diameter); + } + if (distance > highestDistance) { + secondHighestDistance = highestDistance; + highestDistance = distance; + } else if (distance > secondHighestDistance) { + secondHighestDistance = distance; + } + } + diameter[0] = Math.max(diameter[0], highestDistance + secondHighestDistance); + return highestDistance; + } +} diff --git a/Medium/Triangle.java b/Medium/Triangle.java new file mode 100644 index 00000000..0d4a8b54 --- /dev/null +++ b/Medium/Triangle.java @@ -0,0 +1,19 @@ +class Solution { + public int minimumTotal(List> triangle) { + Map dp = new HashMap<>(); + return minimumTotalHelper(triangle, dp, 0, 0); + } + + private int minimumTotalHelper(List> triangle, Map dp, int row, int col) { + String key = row + "|" + col; + if (dp.containsKey(key)) { + return dp.get(key); + } + int path = triangle.get(row).get(col); + if (row < triangle.size() - 1) { + path += Math.min(minimumTotalHelper(triangle, dp, row + 1, col), minimumTotalHelper(triangle, dp, row + 1, col + 1)); + } + dp.put(key, path); + return dp.get(key); + } +} diff --git a/Medium/Trim a Binary Search Tree.java b/Medium/Trim a Binary Search Tree.java new file mode 100644 index 00000000..d7b8d9ff --- /dev/null +++ b/Medium/Trim a Binary Search Tree.java @@ -0,0 +1,30 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public TreeNode trimBST(TreeNode root, int low, int high) { + if (root == null) { + return null; + } + if (root.val < low) { + return trimBST(root.right, low, high); + } else if (root.val > high) { + return trimBST(root.left, low, high); + } + root.left = trimBST(root.left, low, high); + root.right = trimBST(root.right, low, high); + return root; + } +} diff --git a/Medium/Tuple With Same Product.java b/Medium/Tuple With Same Product.java new file mode 100644 index 00000000..fa9165e6 --- /dev/null +++ b/Medium/Tuple With Same Product.java @@ -0,0 +1,14 @@ +class Solution { + public int tupleSameProduct(int[] nums) { + int count = 0; + Map map = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + for (int j = i + 1; j < nums.length; j++) { + int prod = nums[i] * nums[j]; + count += map.getOrDefault(prod, 0); + map.put(prod, map.getOrDefault(prod, 0) + 1); + } + } + return count * 8; + } +} diff --git a/Medium/Tweet Counts Per Frequency.java b/Medium/Tweet Counts Per Frequency.java new file mode 100644 index 00000000..9d58d990 --- /dev/null +++ b/Medium/Tweet Counts Per Frequency.java @@ -0,0 +1,36 @@ +class TweetCounts { + + private final Map> map; + private static final Map INTERVAL_MAP = Map.of( + "minute", 60, + "hour", 3600, + "day", 86400); + + public TweetCounts() { + this.map = new HashMap<>(); + } + + public void recordTweet(String tweetName, int time) { + map.computeIfAbsent(tweetName, k -> new TreeMap<>()); + map.get(tweetName).merge(time, 1, Integer::sum); + } + + public List getTweetCountsPerFrequency(String freq, String tweetName, int startTime, int endTime) { + int interval = INTERVAL_MAP.get(freq); + int size = ((endTime - startTime) / interval + 1); + int[] buckets = new int[size]; + TreeMap frequencyMap = map.get(tweetName); + for (Integer key : frequencyMap.subMap(startTime, endTime + 1).keySet()) { + int idx = (key - startTime) / interval; + buckets[idx] += frequencyMap.get(key); + } + return Arrays.stream(buckets).boxed().collect(Collectors.toList()); + } +} + +/** + * Your TweetCounts object will be instantiated and called as such: + * TweetCounts obj = new TweetCounts(); + * obj.recordTweet(tweetName,time); + * List param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime); + */ diff --git a/Medium/Two City Scheduling.java b/Medium/Two City Scheduling.java new file mode 100644 index 00000000..6f75aeda --- /dev/null +++ b/Medium/Two City Scheduling.java @@ -0,0 +1,11 @@ +class Solution { + public int twoCitySchedCost(int[][] costs) { + Arrays.sort(costs, (o1, o2) -> o1[0] - o1[1] - (o2[0] - o2[1])); + int total = 0; + int n = costs.length / 2; + for (int i = 0; i < n; ++i) { + total += costs[i][0] + costs[i + n][1]; + } + return total; + } +} diff --git a/Medium/Two Sum BSTs.java b/Medium/Two Sum BSTs.java index 1a796d58..d6dd2cf3 100644 --- a/Medium/Two Sum BSTs.java +++ b/Medium/Two Sum BSTs.java @@ -15,35 +15,27 @@ */ class Solution { public boolean twoSumBSTs(TreeNode root1, TreeNode root2, int target) { - if (root1 == null || root2 == null) { - return false; - } + ArrayDeque stack = new ArrayDeque<>(); Set set = new HashSet<>(); - Queue queue = new LinkedList<>(); - queue.add(root2); - while (!queue.isEmpty()) { - TreeNode removed = queue.remove(); - set.add(removed.val); - if (removed.left != null) { - queue.add(removed.left); - } - if (removed.right != null) { - queue.add(removed.right); + while (!stack.isEmpty() || root1 != null) { + while (root1 != null) { + stack.push(root1); + root1 = root1.left; } + root1 = stack.pop(); + set.add(target - root1.val); + root1 = root1.right; } - queue = new LinkedList<>(); - queue.add(root1); - while (!queue.isEmpty()) { - TreeNode removed = queue.remove(); - if (set.contains(target - removed.val)) { - return true; + while (!stack.isEmpty() || root2 != null) { + while (root2 != null) { + stack.push(root2); + root2 = root2.left; } - if (removed.left != null) { - queue.add(removed.left); - } - if (removed.right != null) { - queue.add(removed.right); + root2 = stack.pop(); + if (set.contains(root2.val)) { + return true; } + root2 = root2.right; } return false; } diff --git a/Medium/Two Sum II - Input Array Is Sorted.java b/Medium/Two Sum II - Input Array Is Sorted.java new file mode 100644 index 00000000..f896157c --- /dev/null +++ b/Medium/Two Sum II - Input Array Is Sorted.java @@ -0,0 +1,17 @@ +class Solution { + public int[] twoSum(int[] numbers, int target) { + int leftIdx = 0; + int rightIdx = numbers.length - 1; + while (leftIdx < rightIdx) { + int currSum = numbers[leftIdx] + numbers[rightIdx]; + if (currSum == target) { + return new int[]{leftIdx + 1, rightIdx + 1}; + } else if (currSum > target) { + rightIdx--; + } else { + leftIdx++; + } + } + return new int[]{0}; + } +} diff --git a/Medium/UTF-8 Validation.java b/Medium/UTF-8 Validation.java new file mode 100644 index 00000000..bf7140f0 --- /dev/null +++ b/Medium/UTF-8 Validation.java @@ -0,0 +1,31 @@ +class Solution { + public boolean validUtf8(int[] data) { + int numberOfBytes = 0; + for (int i = 0; i < data.length; i++) { + String binaryRep = Integer.toBinaryString(data[i]); + binaryRep = binaryRep.length() >= 8 ? + binaryRep.substring(binaryRep.length() - 8) : + "00000000".substring(binaryRep.length() % 8) + binaryRep; + if (numberOfBytes == 0) { + for (int j = 0; j < binaryRep.length(); j++) { + if (binaryRep.charAt(j) == '0') { + break; + } + numberOfBytes++; + } + if (numberOfBytes == 0) { + continue; + } + if (numberOfBytes > 4 || numberOfBytes == 1) { + return false; + } + } else { + if (!(binaryRep.charAt(0) == '1' && binaryRep.charAt(1) == '0')) { + return false; + } + } + numberOfBytes--; + } + return numberOfBytes == 0; + } +} diff --git a/Medium/Uncrossed Lines.java b/Medium/Uncrossed Lines.java index 6a923dfa..729da13d 100644 --- a/Medium/Uncrossed Lines.java +++ b/Medium/Uncrossed Lines.java @@ -1,23 +1,21 @@ class Solution { - Integer[][] dp; - public int maxUncrossedLines(int[] A, int[] B) { - dp = new Integer[A.length][B.length]; - return helper(A, 0, B, 0); - } - - private int helper(int[] A, int idxA, int[] B, int idxB) { - if (idxA == A.length || idxB == B.length) { - return 0; - } - if (dp[idxA][idxB] != null) { - return dp[idxA][idxB]; + public int maxUncrossedLines(int[] nums1, int[] nums2) { + Integer[][] dp = new Integer[nums1.length][nums2.length]; + return helper(nums1, 0, nums2, 0, dp); } - if (A[idxA] == B[idxB]) { - dp[idxA][idxB] = 1 + helper(A, idxA + 1, B, idxB + 1); + + private int helper(int[] nums1, int idxOne, int[] nums2, int idxTwo, Integer[][] dp) { + if (idxOne == nums1.length || idxTwo == nums2.length) { + return 0; + } + if (dp[idxOne][idxTwo] != null) { + return dp[idxOne][idxTwo]; + } + if (nums1[idxOne] == nums2[idxTwo]) { + return dp[idxOne][idxTwo] = 1 + helper(nums1, idxOne + 1, nums2, idxTwo + 1, dp); + } + return dp[idxOne][idxTwo] = Math.max( + helper(nums1, idxOne, nums2, idxTwo + 1, dp), + helper(nums1, idxOne + 1, nums2, idxTwo, dp)); } - else { - dp[idxA][idxB] = Math.max(helper(A, idxA + 1, B, idxB), helper(A, idxA, B, idxB + 1)); - } - return dp[idxA][idxB]; - } } diff --git a/Medium/Unique Paths.java b/Medium/Unique Paths.java index 5bea1273..87e5f34e 100644 --- a/Medium/Unique Paths.java +++ b/Medium/Unique Paths.java @@ -1,21 +1,14 @@ class Solution { - Integer[][] dp; public int uniquePaths(int m, int n) { - dp = new Integer[m][n]; - return dfs(m, n, 0, 0); - } - - private int dfs(int m, int n, int x, int y) { - if (x >= m || y >= n) { - return 0; - } - if (dp[x][y] != null) { - return dp[x][y]; + int[][] dp = new int[m][n]; + for (int[] arr : dp) { + Arrays.fill(arr, 1); } - if (x == m - 1 && y == n - 1) { - return 1; + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; + } } - dp[x][y] = dfs(m, n, x + 1, y) + dfs(m, n, x, y + 1); - return dp[x][y]; + return dp[m - 1][n - 1]; } } diff --git a/Medium/Unique Word Abbrevation.java b/Medium/Unique Word Abbrevation.java index 096a2b2a..4cb79291 100644 --- a/Medium/Unique Word Abbrevation.java +++ b/Medium/Unique Word Abbrevation.java @@ -1,41 +1,33 @@ class ValidWordAbbr { - Map map; - public ValidWordAbbr(String[] dictionary) { - map = new HashMap<>(); - - for (String word : dictionary) { - String abbr = getAbbr(word); - if (map.containsKey(abbr)) { - if (!map.get(abbr).equals(word)) { - map.put(abbr, ""); - } - } - else { - map.put(abbr, word); - } - } - } - - public boolean isUnique(String word) { - String abbr = getAbbr(word); - return !map.containsKey(abbr) || map.get(abbr).equals(word); + private final Map abbreviationToWordMap; + + public ValidWordAbbr(String[] dictionary) { + this.abbreviationToWordMap = new HashMap<>(); + for (String word : dictionary) { + String abbreviation = buildAbbreviation(word); + if (this.abbreviationToWordMap.containsKey(abbreviation) && + !this.abbreviationToWordMap.get(abbreviation).equals(word)) { + this.abbreviationToWordMap.put(abbreviation, ""); + } else { + this.abbreviationToWordMap.put(abbreviation, word); + } } + } - private String getAbbr(String word) { - if (word.length() <= 2) { - return word; - } + public boolean isUnique(String word) { + String abbreviation = buildAbbreviation(word); + return !this.abbreviationToWordMap.containsKey(abbreviation) || this.abbreviationToWordMap.get( + abbreviation).equals(word); + } - int num = word.length() - 2; - StringBuilder sb = new StringBuilder(); - sb.append(word.charAt(0)).append(String.valueOf(num)).append(word.charAt(word.length()-1)); - - return sb.toString(); + private String buildAbbreviation(String s) { + if (s.length() <= 2) { + return s; } + return s.charAt(0) + String.valueOf(s.length() - 2) + s.charAt(s.length() - 1); + } } - - /** * Your ValidWordAbbr object will be instantiated and called as such: * ValidWordAbbr obj = new ValidWordAbbr(dictionary); diff --git a/Medium/Using a Robot to Print the Lexicographically Smallest String.java b/Medium/Using a Robot to Print the Lexicographically Smallest String.java new file mode 100644 index 00000000..8d9c2064 --- /dev/null +++ b/Medium/Using a Robot to Print the Lexicographically Smallest String.java @@ -0,0 +1,31 @@ +class Solution { + public String robotWithString(String s) { + int[] counter = new int[26]; + for (char c : s.toCharArray()) { + counter[c - 'a']++; + } + Stack stack = new Stack<>(); + StringBuilder sb = new StringBuilder(); + for (char c : s.toCharArray()) { + stack.push(c); + counter[c - 'a']--; + while (!stack.isEmpty() && isSmallest(stack.peek(), counter)) { + sb.append(stack.pop()); + } + } + while (!stack.isEmpty()) { + sb.append(stack.pop()); + } + return sb.toString(); + } + + private boolean isSmallest(char c, int[] counter) { + int limit = c - 'a'; + for (int i = 0; i < limit; i++) { + if (counter[i] > 0) { + return false; + } + } + return true; + } +} diff --git a/Medium/Valid Square.java b/Medium/Valid Square.java new file mode 100644 index 00000000..31a72df4 --- /dev/null +++ b/Medium/Valid Square.java @@ -0,0 +1,17 @@ +class Solution { + public boolean validSquare(int[] p1, int[] p2, int[] p3, int[] p4) { + int[][] points = {p1, p2, p3, p4}; + Arrays.sort(points, (i1, i2) -> i2[0] == i1[0] ? i1[1] - i2[1] : i1[0] - i2[0]); + return ( + getDistance(points[0], points[1]) != 0 && + getDistance(points[0], points[1]) == getDistance(points[1], points[3]) && + getDistance(points[1], points[3]) == getDistance(points[3], points[2]) && + getDistance(points[3], points[2]) == getDistance(points[2], points[0]) && + getDistance(points[0],points[3])==getDistance(points[1],points[2]) + ); + } + + private double getDistance(int[] p1, int[] p2) { + return (p2[1] - p1[1]) * (p2[1] - p1[1]) + (p2[0] - p1[0]) * (p2[0] - p1[0]); + } +} diff --git a/Medium/Valid Sudoku.java b/Medium/Valid Sudoku.java index e35dd7c3..88538727 100644 --- a/Medium/Valid Sudoku.java +++ b/Medium/Valid Sudoku.java @@ -1,27 +1,30 @@ class Solution { - public boolean isValidSudoku(char[][] board) { - HashSet[] rowSet = new HashSet[9]; - HashSet[] colSet = new HashSet[9]; - HashSet[] boxSet = new HashSet[9]; - for (int i = 0; i < 9; i++) { - rowSet[i] = new HashSet<>(); - colSet[i] = new HashSet<>(); - boxSet[i] = new HashSet<>(); + public boolean isValidSudoku(char[][] board) { + int N = 9; + int[][] rows = new int[N][N]; + int[][] cols = new int[N][N]; + int[][] boxes = new int[N][N]; + for (int r = 0; r < N; r++) { + for (int c = 0; c < N; c++) { + if (board[r][c] == '.') { + continue; } - for (int i = 0; i < 9; i++) { - for (int j = 0; j < 9; j++) { - if (board[i][j] != '.') { - char val = board[i][j]; - int boxIdx = (i / 3) * 3 + j / 3; - if (rowSet[i].contains(val) || colSet[j].contains(val) || boxSet[boxIdx].contains(val)) { - return false; - } - rowSet[i].add(val); - colSet[j].add(val); - boxSet[boxIdx].add(val); - } - } + int pos = board[r][c] - '1'; + if (rows[r][pos] == 1) { + return false; } - return true; + rows[r][pos] = 1; + if (cols[c][pos] == 1) { + return false; + } + cols[c][pos] = 1; + int idx = (r / 3) * 3 + c / 3; + if (boxes[idx][pos] == 1) { + return false; + } + boxes[idx][pos] = 1; + } } + return true; + } } diff --git a/Medium/Validate Binary Search Tree.java b/Medium/Validate Binary Search Tree.java index b7d2a9f7..7989ffbf 100644 --- a/Medium/Validate Binary Search Tree.java +++ b/Medium/Validate Binary Search Tree.java @@ -4,23 +4,27 @@ * int val; * TreeNode left; * TreeNode right; - * TreeNode(int x) { val = x; } + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } * } */ class Solution { public boolean isValidBST(TreeNode root) { - long min = (long) Integer.MIN_VALUE; - long max = (long) Integer.MAX_VALUE; - return helper(root, min - 1, max + 1); + return isValidBSTHelper(root, (((long) Integer.MAX_VALUE) + 1), ((long) Integer.MIN_VALUE) - 1); } - private boolean helper(TreeNode root, long min, long max) { - if (root == null) { + private boolean isValidBSTHelper(TreeNode node, long max, long min) { + if (node == null) { return true; } - if (root.val <= min || root.val >= max) { + if (node.val >= max || node.val <= min) { return false; } - return helper(root.left, min, (long) root.val) && helper(root.right, (long) root.val, max); + return isValidBSTHelper(node.left, node.val, min) && isValidBSTHelper(node.right, max, node.val); } } diff --git a/Medium/Validate Stack Sequences.java b/Medium/Validate Stack Sequences.java index aa3c8470..64ae1452 100644 --- a/Medium/Validate Stack Sequences.java +++ b/Medium/Validate Stack Sequences.java @@ -1,29 +1,20 @@ class Solution { - public boolean validateStackSequences(int[] pushed, int[] popped) { - int pushStart = 0; - int popStart = 0; - Stack stack = new Stack<>(); - while (pushStart < pushed.length && popStart < popped.length) { - if (stack.isEmpty()) { - stack.push(pushed[pushStart++]); - } - else { - if (stack.peek() == popped[popStart]) { - stack.pop(); - popStart++; + public boolean validateStackSequences(int[] pushed, int[] popped) { + Stack stack = new Stack<>(); + int pushedIdx = 0; + int poppedIdx = 0; + while (pushedIdx < pushed.length && poppedIdx < popped.length) { + if (!stack.isEmpty() && stack.peek() == popped[poppedIdx]) { + stack.pop(); + poppedIdx++; + } else { + stack.push(pushed[pushedIdx++]); + } } - else { - stack.push(pushed[pushStart++]); + while (poppedIdx < popped.length && !stack.isEmpty() && stack.peek() == popped[poppedIdx]) { + stack.pop(); + poppedIdx++; } - } + return pushedIdx == pushed.length && poppedIdx == popped.length; } - while (popStart < popped.length) { - if (stack.peek() != popped[popStart]) { - return false; - } - stack.pop(); - popStart++; - } - return true; - } } diff --git a/Medium/Verify Preorder Serialization of a Binary Tree.java b/Medium/Verify Preorder Serialization of a Binary Tree.java index 3e1b5151..db43f945 100644 --- a/Medium/Verify Preorder Serialization of a Binary Tree.java +++ b/Medium/Verify Preorder Serialization of a Binary Tree.java @@ -1,24 +1,15 @@ class Solution { - public boolean isValidSerialization(String preorder) { - Stack stack = new Stack<>(); - String[] array = preorder.split(","); - - for (String node : array) { - if (node.equals("#")) { - while (!stack.isEmpty() && stack.peek().equals("#")) { - stack.pop(); - if (stack.isEmpty()) { - return false; - } - stack.pop(); - } - stack.push(node); - } - else { - stack.push(node); - } - } - - return stack.size() == 1 && stack.peek().equals("#"); + 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; + } } diff --git a/Medium/Vertical Order Traversal Of Binary Tree.java b/Medium/Vertical Order Traversal Of Binary Tree.java deleted file mode 100644 index 0459a5f6..00000000 --- a/Medium/Vertical Order Traversal Of Binary Tree.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode(int x) { val = x; } - * } - */ -class Solution { - public List> verticalTraversal(TreeNode root) { - if (root == null) { - return new ArrayList<>(); - } - Map> map = new TreeMap<>(); - Queue queue = new LinkedList<>(); - queue.add(new TreeLevel(root, 0, 0)); - while (!queue.isEmpty()) { - int size = queue.size(); - while (size-- > 0) { - TreeLevel removed = queue.remove(); - map.computeIfAbsent(removed.xLevel, k -> new ArrayList<>()).add(removed); - if (removed.node.left != null) { - queue.add(new TreeLevel(removed.node.left, removed.xLevel - 1, removed.yLevel - 1)); - } - if (removed.node.right != null) { - queue.add(new TreeLevel(removed.node.right, removed.xLevel + 1, removed.yLevel - 1)); - } - } - } - List> list = new ArrayList<>(); - for (Integer key : map.keySet()) { - List temp = map.get(key); - Collections.sort(temp, new Comparator(){ - public int compare(TreeLevel t1, TreeLevel t2) { - int c = t2.yLevel - t1.yLevel; - if (c == 0) { - c = t1.node.val - t2.node.val; - } - return c; - } - }); - List valTemp = new ArrayList<>(); - for (TreeLevel t : temp) { - valTemp.add(t.node.val); - } - list.add(valTemp); - } - return list; - } -} - -class TreeLevel { - TreeNode node; - int xLevel; - int yLevel; - - public TreeLevel(TreeNode node, int xLevel, int yLevel) { - this.node = node; - this.xLevel = xLevel; - this.yLevel = yLevel; - } -} diff --git a/Medium/Vowels of All Substrings.java b/Medium/Vowels of All Substrings.java new file mode 100644 index 00000000..c54486eb --- /dev/null +++ b/Medium/Vowels of All Substrings.java @@ -0,0 +1,12 @@ +class Solution { + public long countVowels(String word) { + long sum = 0; + long n = word.length(); + for (int i = 0; i < n; i++) { + if ("aeiou".indexOf(word.charAt(i)) != -1) { + sum += (i + 1) * (n - i); + } + } + return sum; + } +} diff --git a/Medium/Walking Robot Simulation.java b/Medium/Walking Robot Simulation.java new file mode 100644 index 00000000..bfc2784f --- /dev/null +++ b/Medium/Walking Robot Simulation.java @@ -0,0 +1,41 @@ +class Solution { + private static final int[][] DIRECTIONS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; + private static final int HASH_MULTIPLIER = 60001; + + public int robotSim(int[] commands, int[][] obstacles) { + Set obstacleSet = new HashSet<>(); + for (int[] obstacle : obstacles) { + obstacleSet.add(hashCoordinates(obstacle[0], obstacle[1])); + } + int maxDistance = 0; + int currentDirection = 0; + int x = 0; + int y = 0; + for (int command : commands) { + if (command == -1) { + currentDirection = (currentDirection + 1) % 4; + continue; + } + if (command == -2) { + currentDirection = (currentDirection + 3) % 4; + continue; + } + int[] direction = DIRECTIONS[currentDirection]; + for (int i = 0; i < command; i++) { + int nextX = x + direction[0]; + int nextY = y + direction[1]; + if (obstacleSet.contains(hashCoordinates(nextX, nextY))) { + break; + } + x = nextX; + y = nextY; + } + maxDistance = Math.max(maxDistance, x * x + y * y); + } + return maxDistance; + } + + private static int hashCoordinates(int x, int y) { + return x + HASH_MULTIPLIER * y; + } +} diff --git a/Medium/Water Bottles II.java b/Medium/Water Bottles II.java new file mode 100644 index 00000000..d9205f31 --- /dev/null +++ b/Medium/Water Bottles II.java @@ -0,0 +1,12 @@ +class Solution { + public int maxBottlesDrunk(int numBottles, int numExchange) { + int total = numBottles; + while (numBottles >= numExchange) { + numBottles -= numExchange; + numExchange++; + total++; + numBottles++; + } + return total; + } +} diff --git a/Medium/Watering Plants.java b/Medium/Watering Plants.java new file mode 100644 index 00000000..afa36ee2 --- /dev/null +++ b/Medium/Watering Plants.java @@ -0,0 +1,16 @@ +class Solution { + public int wateringPlants(int[] plants, int capacity) { + int idx = 0; + int currCapacity = capacity; + int totalSteps = 0; + while (idx < plants.length) { + if (currCapacity < plants[idx]) { + currCapacity = capacity; + totalSteps += 2 * idx; + } + currCapacity -= plants[idx++]; + totalSteps++; + } + return totalSteps; + } +} diff --git a/Medium/Web Crawler.java b/Medium/Web Crawler.java index 2eafccb7..57737330 100644 --- a/Medium/Web Crawler.java +++ b/Medium/Web Crawler.java @@ -5,27 +5,29 @@ * public List getUrls(String url) {} * } */ + class Solution { - public List crawl(String startUrl, HtmlParser htmlParser) { - Set visited = new HashSet<>(); - Stack stack = new Stack<>(); - stack.push(startUrl); - String hostname = getHostname(startUrl); - while(!stack.isEmpty()) { - String popped = stack.pop(); - visited.add(popped); - List connectedUrls = htmlParser.getUrls(popped); - for (String url : connectedUrls) { - if (!visited.contains(url) && url.contains(hostname)) { - stack.push(url); - } - } + public List crawl(String startUrl, HtmlParser htmlParser) { + int startIdx = startUrl.indexOf("//") + 2; + int endIdx = startUrl.indexOf("/", startIdx) == -1 ? startUrl.length() : startUrl.indexOf("/", startIdx); + String domain = startUrl.substring(0, endIdx); + Set visitedUrls = new HashSet<>(); + Queue queue = new LinkedList<>(); + queue.add(startUrl); + while (!queue.isEmpty()) { + int size = queue.size(); + while (size-- > 0) { + String removed = queue.remove(); + visitedUrls.add(removed); + List urls = htmlParser.getUrls(removed); + for (String url : urls) { + if (url.startsWith(domain) && !visitedUrls.contains(url)) { + visitedUrls.add(url); + queue.add(url); + } } - return new ArrayList<>(visited); - } - - private String getHostname(String url) { - String[] splits = url.split("/"); - return splits[2]; + } } + return new ArrayList<>(visitedUrls); + } } diff --git a/Medium/Widest Vertical Area Between Two Points Containing No Points.java b/Medium/Widest Vertical Area Between Two Points Containing No Points.java new file mode 100644 index 00000000..d2e07d21 --- /dev/null +++ b/Medium/Widest Vertical Area Between Two Points Containing No Points.java @@ -0,0 +1,11 @@ +class Solution { + public int maxWidthOfVerticalArea(int[][] points) { + Arrays.sort(points, (a, b) -> a[0] - b[0]); + int maxWidth = 0; + for (int i = 1; i < points.length; i++) { + int width = points[i][0] - points[i - 1][0]; + maxWidth = Math.max(maxWidth, width); + } + return maxWidth; + } +} diff --git a/Medium/Wiggle Sort.java b/Medium/Wiggle Sort.java index e4e8ad13..68cac74b 100644 --- a/Medium/Wiggle Sort.java +++ b/Medium/Wiggle Sort.java @@ -1,24 +1,11 @@ class Solution { - public void wiggleSort(int[] nums) { - boolean small = true; - for (int i = 0; i < nums.length - 1; i++) { - if (small) { - if (nums[i] > nums[i + 1]) { - swap(nums, i, i + 1); + public void wiggleSort(int[] nums) { + for (int i = 1; i < nums.length; i++) { + if ((i % 2 == 1 && nums[i] < nums[i - 1]) || (i % 2 != 1 && nums[i] > nums[i - 1])) { + int temp = nums[i]; + nums[i] = nums[i - 1]; + nums[i - 1] = temp; + } } - } - else { - if (nums[i] < nums[i + 1]) { - swap(nums, i, i + 1); - } - } - small = !small; } - } - - private void swap(int[] nums, int idx1, int idx2) { - int temp = nums[idx2]; - nums[idx2] = nums[idx1]; - nums[idx1] = temp; - } } diff --git a/Medium/Wiggle Subsequence.java b/Medium/Wiggle Subsequence.java new file mode 100644 index 00000000..4e066527 --- /dev/null +++ b/Medium/Wiggle Subsequence.java @@ -0,0 +1,19 @@ +class Solution { + public int wiggleMaxLength(int[] nums) { + if (nums.length < 2) { + return nums.length; + } + int[] increasing = new int[nums.length]; + int[] decreasing = new int[nums.length]; + for (int i = 0; i < nums.length; i++) { + for (int j = 0; j < i; j++) { + if (nums[i] > nums[j]) { + increasing[i] = Math.max(increasing[i], decreasing[j] + 1); + } else if (nums[i] < nums[j]) { + decreasing[i] = Math.max(decreasing[i], increasing[j] + 1); + } + } + } + return 1 + Math.max(decreasing[nums.length - 1], increasing[nums.length - 1]); + } +} diff --git a/Medium/Word Search.java b/Medium/Word Search.java index f5ed8288..5a63db20 100644 --- a/Medium/Word Search.java +++ b/Medium/Word Search.java @@ -1,33 +1,33 @@ class Solution { - public int[][] dirs = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; - public boolean exist(char[][] board, String word) { - if (board.length == 0 || board[0].length == 0) { - return false; - } - for (int i = 0; i < board.length; i++) { - for (int j = 0; j < board[0].length; j++) { - if (exists(board, i, j, word, 0, new boolean[board.length][board[0].length])) { - return true; + + private static final int[][] DIRS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; + + public boolean exist(char[][] board, String word) { + int m = board.length; + int n = board[0].length; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (isFound(board, word, 0, i, j, m, n)) { + return true; + } + } } - } - } - return false; - } - - private boolean exists(char[][] board, int i, int j, String word, int idx, boolean[][] visited) { - if (idx == word.length()) { - return true; - } - if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || visited[i][j] || word.charAt(idx) != board[i][j]) { - return false; + return false; } - visited[i][j] = true; - for (int[] dir : dirs) { - if (exists(board, i + dir[0], j + dir[1], word, idx + 1, visited)) { - return true; - } + + private boolean isFound(char[][] board, String word, int idx, int row, int col, int m, int n) { + if (idx == word.length()) { + return true; + } + if (row < 0 || col < 0 || row >= m || col >= n || board[row][col] != word.charAt(idx)) { + return false; + } + board[row][col] ^= 256; + boolean result = false; + for (int[] dir : DIRS) { + result = result || isFound(board, word, idx + 1, row + dir[0], col + dir[1], m, n); + } + board[row][col] ^= 256; + return result; } - visited[i][j] = false; - return false; - } } diff --git a/Medium/Word Subsets.java b/Medium/Word Subsets.java new file mode 100644 index 00000000..9c93be7d --- /dev/null +++ b/Medium/Word Subsets.java @@ -0,0 +1,32 @@ +class Solution { + public List wordSubsets(String[] words1, String[] words2) { + int[] word2MaxCount = new int[26]; + for (String word : words2) { + int[] count = getFrequencyArray(word); + for (int i = 0; i < 26; i++) { + word2MaxCount[i] = Math.max(word2MaxCount[i], count[i]); + } + } + List result = new ArrayList<>(); + for (String word : words1) { + int[] count = getFrequencyArray(word); + for (int i = 0; i < 26; i++) { + if (count[i] < word2MaxCount[i]) { + break; + } + if (i == 25) { + result.add(word); + } + } + } + return result; + } + + private static int[] getFrequencyArray(String s) { + int[] count = new int[26]; + for (char c : s.toCharArray()) { + count[c - 'a']++; + } + return count; + } +} diff --git a/Medium/XOR Queries of a Subarray.java b/Medium/XOR Queries of a Subarray.java new file mode 100644 index 00000000..0bdfc9ca --- /dev/null +++ b/Medium/XOR Queries of a Subarray.java @@ -0,0 +1,24 @@ +class Solution { + public int[] xorQueries(int[] arr, int[][] queries) { + int n = arr.length; + int[] prefixXors = new int[n]; + int xor = 0; + for (int i = 0; i < n; i++) { + xor = xor ^ arr[i]; + prefixXors[i] = xor; + } + n = queries.length; + int[] result = new int[n]; + for (int i = 0; i < n; i++) { + int[] query = queries[i]; + int left = query[0]; + int right = query[1]; + int xorResult = prefixXors[right]; + if (left != 0) { + xorResult = xorResult ^ prefixXors[left - 1]; + } + result[i] = xorResult; + } + return result; + } +} diff --git a/Medium/Zero Array Transformation I.java b/Medium/Zero Array Transformation I.java new file mode 100644 index 00000000..2b9ab602 --- /dev/null +++ b/Medium/Zero Array Transformation I.java @@ -0,0 +1,24 @@ +class Solution { + public boolean isZeroArray(int[] nums, int[][] queries) { + int n = nums.length; + int[] diff = new int[n + 1]; + for (int[] query : queries) { + int left = query[0]; + int right = query[1]; + diff[left] += 1; + diff[right + 1] -= 1; + } + int[] operation = new int[n + 1]; + int currOperation = 0; + for (int i = 0; i < n + 1; i++) { + currOperation += diff[i]; + operation[i] = currOperation; + } + for (int i = 0; i < n; i++) { + if (operation[i] < nums[i]) { + return false; + } + } + return true; + } +} diff --git a/Medium/ZigZag Conversion.java b/Medium/ZigZag Conversion.java index d3c2cc5c..31793633 100644 --- a/Medium/ZigZag Conversion.java +++ b/Medium/ZigZag Conversion.java @@ -1,26 +1,29 @@ class Solution { public String convert(String s, int numRows) { - List list = new ArrayList<>(); + if (numRows == 1) { + return s; + } + StringBuilder[] rows = new StringBuilder[numRows]; for (int i = 0; i < numRows; i++) { - list.add(new StringBuilder()); + rows[i] = new StringBuilder(); } - + int row = 0; + int n = s.length(); int idx = 0; - while (idx < s.length()) { - for (int i = 0; i < numRows && idx < s.length(); i++) { - list.get(i).append(s.charAt(idx++)); + while (idx < n) { + while (idx < n && row < numRows) { + rows[row++].append(s.charAt(idx++)); } - - for (int i = numRows - 2; i > 0 && idx < s.length(); i--) { - list.get(i).append(s.charAt(idx++)); + row -= 2; + while (idx < n && row >= 0) { + rows[row--].append(s.charAt(idx++)); } + row += 2; } - - StringBuilder ans = new StringBuilder(); - for (StringBuilder sb : list) { - ans.append(sb.toString()); + StringBuilder result = new StringBuilder(); + for (StringBuilder sb : rows) { + result.append(sb.toString()); } - - return ans.toString(); + return result.toString(); } } diff --git a/Medium/Zigzag Iterator.java b/Medium/Zigzag Iterator.java index 442497c1..1b4f8554 100644 --- a/Medium/Zigzag Iterator.java +++ b/Medium/Zigzag Iterator.java @@ -1,52 +1,35 @@ public class ZigzagIterator { - - List l1; - List l2; - int start1; - int start2; - int end1; - int end2; - boolean flag; - - public ZigzagIterator(List v1, List v2) { - l1 = v1; - l2 = v2; - start1 = 0; - start2 = 0; - end1 = l1.size(); - end2 = l2.size(); - flag = true; - } - public int next() { - if (start1 < end1 && start2 < end2) { - int ans = -1; - if (flag) { - ans = l1.get(start1); - start1++; - flag = !flag; - } - else { - ans = l2.get(start2); - start2++; - flag = !flag; - } - - return ans; - } - else if (start1 < end1) { - return l1.get(start1++); - } - else { - return l2.get(start2++); - } - } + private final List listOne; + private final List listTwo; + int idxOne; + int idxTwo; + boolean pickFromListOne; + public ZigzagIterator(List v1, List v2) { + this.listOne = v1; + this.listTwo = v2; + this.idxOne = 0; + this.idxTwo = 0; + this.pickFromListOne = true; + } - public boolean hasNext() { - return !(start1 == end1 && start2 == end2); + public int next() { + if ((pickFromListOne && idxOne < listOne.size()) || (!pickFromListOne + && idxTwo == listTwo.size())) { + pickFromListOne = !pickFromListOne; + return listOne.get(idxOne++); } + pickFromListOne = !pickFromListOne; + return listTwo.get(idxTwo++); + } + + public boolean hasNext() { + return idxOne < listOne.size() || idxTwo < listTwo.size(); + } } + + /** * Your ZigzagIterator object will be instantiated and called as such: * ZigzagIterator i = new ZigzagIterator(v1, v2); diff --git a/README.md b/README.md index 6c48b169..617cd951 100644 --- a/README.md +++ b/README.md @@ -2,5 +2,12 @@ ## Solutions to Leetcode problems in Java -## [Current Leetcode profile: Solved 750+ Problems](https://leetcode.com/varunsjsu/) +## [Current Leetcode profile: Solved 1700+ Problems](https://leetcode.com/varunsjsu/) ## [Previous Leetcode profile: Solved 759 Problems](https://leetcode.com/varunu28/) + +Problem Category | Count +--- | --- +[Easy](https://github.com/varunu28/LeetCode-Java-Solutions/blob/master/Easy/README.md) | 607 +[Medium](https://github.com/varunu28/LeetCode-Java-Solutions/blob/master/Medium/README.md) | 793 +[Hard](https://github.com/varunu28/LeetCode-Java-Solutions/blob/master/Hard/README.md) | 125 +[Concurrency](https://github.com/varunu28/LeetCode-Java-Solutions/blob/master/Concurrency/README.md) | 9 diff --git a/commit-script.sh b/commit-script.sh new file mode 100755 index 00000000..90a4f404 --- /dev/null +++ b/commit-script.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +git add . + +if git status | grep -q 'modified'; then + status=$(git status | grep 'modified') + modified_file=${status##*/} + git commit -m "Updated ${modified_file}" +elif git status | grep -q 'new file:'; then + status=$(git status | grep 'new file:') + added_file=${status##*/} + git commit -m "Added ${added_file}" +fi + +git push