Fix up leetcode
This commit is contained in:
@@ -3,15 +3,11 @@
|
|||||||
#+description: Description
|
#+description: Description
|
||||||
#+date: 2024-04-29
|
#+date: 2024-04-29
|
||||||
|
|
||||||
* Prelude
|
|
||||||
#+begin_src c++ :session c++
|
|
||||||
test
|
|
||||||
#+end_src
|
|
||||||
* Arrays
|
* Arrays
|
||||||
** DONE (#217) Contains duplicate
|
** DONE (#217) Contains duplicate
|
||||||
If there are any duplicates, then when the list is sorted they would
|
If there are any duplicates, then when the list is sorted they would
|
||||||
be consecutive.
|
be consecutive.
|
||||||
#+begin_src c++ :tangle 217.cpp :session c++
|
#+begin_src c++ :tangle 217.cpp :session c++ :comments link
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -34,7 +30,7 @@ disregarding ordering.
|
|||||||
Sorting the two strings would force the same
|
Sorting the two strings would force the same
|
||||||
order for both strings.
|
order for both strings.
|
||||||
|
|
||||||
#+begin_src c++ :tangle 242-sort.cpp
|
#+begin_src c++ :tangle 242-sort.cpp :comments link
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
bool isAnagram(string s, string t)
|
bool isAnagram(string s, string t)
|
||||||
@@ -45,7 +41,7 @@ bool isAnagram(string s, string t)
|
|||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
*** Simple table
|
*** Simple table
|
||||||
#+begin_src c++ :tangle 242-table.cpp
|
#+begin_src c++ :tangle 242-table.cpp :comments link
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
bool isAnagram(string s, string t)
|
bool isAnagram(string s, string t)
|
||||||
@@ -64,7 +60,7 @@ bool isAnagram(string s, string t)
|
|||||||
#+end_src
|
#+end_src
|
||||||
** DONE (#1) Two sum
|
** DONE (#1) Two sum
|
||||||
Given a target find two elements which sum to it.
|
Given a target find two elements which sum to it.
|
||||||
#+begin_src c++ :tangle 1.cpp
|
#+begin_src c++ :tangle 1.cpp :comments link
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
vector<int> twoSum(vector<int> &nums, int target)
|
vector<int> twoSum(vector<int> &nums, int target)
|
||||||
@@ -81,7 +77,7 @@ vector<int> twoSum(vector<int> &nums, int target)
|
|||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
** DONE (#49) Group anagrams
|
** DONE (#49) Group anagrams
|
||||||
#+begin_src c++ :tangle 49.cpp
|
#+begin_src c++ :tangle 49.cpp :comments link
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
vector<vector<string>> groupAnagrams(vector<string> &strs)
|
vector<vector<string>> groupAnagrams(vector<string> &strs)
|
||||||
@@ -106,7 +102,7 @@ hash tables.
|
|||||||
*** Sorting the map
|
*** Sorting the map
|
||||||
Once you've generated the map, sort it by frequency (then by number)
|
Once you've generated the map, sort it by frequency (then by number)
|
||||||
then take the top k off it.
|
then take the top k off it.
|
||||||
#+begin_src c++ :tangle 347-sort.cpp
|
#+begin_src c++ :tangle 347-sort.cpp :comments link
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
vector<int> topKFrequent(vector<int> &nums, int k)
|
vector<int> topKFrequent(vector<int> &nums, int k)
|
||||||
@@ -138,7 +134,7 @@ value. The priority sorts the members.
|
|||||||
Hence, if we generate the map then place them all in a priority queue,
|
Hence, if we generate the map then place them all in a priority queue,
|
||||||
we just need to get the k highest priority items to finish the
|
we just need to get the k highest priority items to finish the
|
||||||
problem.
|
problem.
|
||||||
#+begin_src c++ :tangle 347-queue.cpp
|
#+begin_src c++ :tangle 347-queue.cpp :comments link
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -174,7 +170,7 @@ i: [x from 0 to i - 1] * i is the product [x from 0 to i]. Same the
|
|||||||
other way. So we can iterate once to produce the products before i
|
other way. So we can iterate once to produce the products before i
|
||||||
and once for the products after i while only doing a set once!
|
and once for the products after i while only doing a set once!
|
||||||
|
|
||||||
#+begin_src c++ :tangle 238.cpp
|
#+begin_src c++ :tangle 238.cpp :comments link
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -201,11 +197,9 @@ Determine if a 9x9 grid is a valid sudoku.
|
|||||||
You can use a set of hashsets (where membership testing is O(1)) to
|
You can use a set of hashsets (where membership testing is O(1)) to
|
||||||
just check if you've seen a number before. In this case, since we
|
just check if you've seen a number before. In this case, since we
|
||||||
know the exact input data and the properties we want we can use
|
know the exact input data and the properties we want we can use
|
||||||
boolean tables to speed up the process.
|
boolean arrays which are smaller and easier for the CPU to work with.
|
||||||
|
|
||||||
I also use a little maths technique to produce a correct ordering of
|
#+begin_src c++ :tangle 36.cpp :comments link
|
||||||
the boxes via integer division.
|
|
||||||
#+begin_src c++ :tangle 36.cpp
|
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -240,7 +234,7 @@ bool isValidSudoku(vector<vector<char>> &board)
|
|||||||
#+end_src
|
#+end_src
|
||||||
** DONE (#128) Longest consecutive sequence
|
** DONE (#128) Longest consecutive sequence
|
||||||
|
|
||||||
#+begin_src c++ :tangle 128.cpp
|
#+begin_src c++ :tangle 128.cpp :comments link
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -260,9 +254,74 @@ int longestConsecutive(vector<int> &nums)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
** DONE (#53) Maximum Subarray
|
||||||
|
Find the maximal sum of a subarray in some array. This is actually a
|
||||||
|
dynamic programming problem.
|
||||||
|
*** Brute force
|
||||||
|
If there's only one element then that is obviously the maximal sum.
|
||||||
|
A brute force approach would compute it every subarray sum and then
|
||||||
|
return the best one.
|
||||||
|
|
||||||
|
#+begin_src c++ :tangle 53-bf.cpp :comments link
|
||||||
|
#include <bits/stdc++.h>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int maxSubArray(vector<int> &nums)
|
||||||
|
{
|
||||||
|
int max_sum = nums[0];
|
||||||
|
for (int i = 1; i < nums.size(); ++i)
|
||||||
|
{
|
||||||
|
// Is nums[i] alone better than what we've made so far?
|
||||||
|
max_sum = std::max(nums[i], max_sum);
|
||||||
|
int cur_sum = 0;
|
||||||
|
for (int j = 0; j <= i; ++j)
|
||||||
|
cur_sum += nums[i];
|
||||||
|
// Is the sum nums[0..i] better than what we've done so far?
|
||||||
|
max_sum = std::max(std::max(cur_sum, max_sum));
|
||||||
|
}
|
||||||
|
return max_sum;
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
O(n^2) but can we do better?
|
||||||
|
*** Dynamic programming
|
||||||
|
Look at the tree of cur_sum's we need to
|
||||||
|
compute:
|
||||||
|
+ at i = 1, cur_sum is sum[0..1]
|
||||||
|
+ at i = 2, cur_sum is sum[0..2]
|
||||||
|
+ at i = k, cur_sum is sum[0..k] = sum[0..k-1] + k
|
||||||
|
|
||||||
|
At each iteration we're essentially checking if nums[i] is better or
|
||||||
|
the sum is better than what we've seen before.
|
||||||
|
|
||||||
|
Obviously the sum is stupidly expensive. Furthermore, we may not even
|
||||||
|
need to do the entire sum; if the best sum starts at k and ends at k'
|
||||||
|
there's literally no point in summing numbers before k in cur_sum. So
|
||||||
|
we may as well introduce that optimisation.
|
||||||
|
#+begin_src c++ :tangle 53-dp.cpp :comments link
|
||||||
|
#+end_src
|
||||||
|
*** Kadane's formulation
|
||||||
|
#+begin_src c++ :tangle 53-kadane.cpp :comments link
|
||||||
|
#include <bits/stdc++.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int maxSubArray(vector<int> &nums)
|
||||||
|
{
|
||||||
|
if (nums.size() == 1)
|
||||||
|
return nums[0];
|
||||||
|
int max_sum = nums[0], cur_sum = nums[0];
|
||||||
|
for (size_t i = 1; i < nums.size(); ++i)
|
||||||
|
{
|
||||||
|
cur_sum = std::max(cur_sum + nums[i], nums[i]);
|
||||||
|
max_sum = std::max(cur_sum, max_sum);
|
||||||
|
}
|
||||||
|
return max_sum;
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
* Stack
|
* Stack
|
||||||
** DONE (#20) Valid Parentheses
|
** DONE (#20) Valid Parentheses
|
||||||
#+begin_src c++ :tangle 20.cpp
|
#+begin_src c++ :tangle 20.cpp :comments link
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -306,7 +365,7 @@ functions in O(1) (what?!).
|
|||||||
In exchange for O(n) memory we can implement most of them.
|
In exchange for O(n) memory we can implement most of them.
|
||||||
Unfortunately all the high performance implementations also use stacks
|
Unfortunately all the high performance implementations also use stacks
|
||||||
(what's the point!).
|
(what's the point!).
|
||||||
#+begin_src c++ :tangle 155.cpp
|
#+begin_src c++ :tangle 155.cpp :comments link
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -360,7 +419,7 @@ Encountered an issue with C/C++'s semantics when it comes prefix
|
|||||||
decrement: it doesn't have an effect until after the statement so the
|
decrement: it doesn't have an effect until after the statement so the
|
||||||
other side of the assignment still considers ~ptr~ to be the same
|
other side of the assignment still considers ~ptr~ to be the same
|
||||||
value. Bit interesting, good to note.
|
value. Bit interesting, good to note.
|
||||||
#+begin_src c++ :tangle 150.cpp
|
#+begin_src c++ :tangle 150.cpp :comments link
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -398,7 +457,7 @@ parentheses.
|
|||||||
*** Naive solution
|
*** Naive solution
|
||||||
I generate all 2^n bit strings (where n = 2 * number of pairs) then
|
I generate all 2^n bit strings (where n = 2 * number of pairs) then
|
||||||
filer all the invalid bit strings.
|
filer all the invalid bit strings.
|
||||||
#+begin_src c++ :tangle 22-naive.cpp
|
#+begin_src c++ :tangle 22-naive.cpp :comments link
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -474,7 +533,7 @@ string (add an open brace or add a closed brace) but only generate the
|
|||||||
second one based on a condition on the first. As we do these
|
second one based on a condition on the first. As we do these
|
||||||
simultaneously we can generate the two possible next steps given an
|
simultaneously we can generate the two possible next steps given an
|
||||||
input string.
|
input string.
|
||||||
#+begin_src c++ :tangle 22-backtrack.cpp
|
#+begin_src c++ :tangle 22-backtrack.cpp :comments link
|
||||||
#include <bits/stdc++.h>
|
#include <bits/stdc++.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -531,3 +590,4 @@ vector<int> dailyTemperatures(vector<int> &temperatures)
|
|||||||
return days;
|
return days;
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
* Blind 75
|
||||||
|
|||||||
Reference in New Issue
Block a user