From c7a3220dee9cbb50b4e342f0e705b72a489c04bf Mon Sep 17 00:00:00 2001 From: tai Date: Thu, 25 Jul 2024 11:56:00 +0700 Subject: [PATCH 01/39] tuantai0708 - Day2507 --- Topic1_Arrays/.gitignore | 229 +++++++++++++++++++++++++++++ Topic1_Arrays/Day2507/Exercise1.cs | 48 ++++++ Topic1_Arrays/Day2507/Exercise2.cs | 45 ++++++ Topic1_Arrays/Day2507/Exercise3.cs | 46 ++++++ 4 files changed, 368 insertions(+) create mode 100644 Topic1_Arrays/.gitignore create mode 100644 Topic1_Arrays/Day2507/Exercise1.cs create mode 100644 Topic1_Arrays/Day2507/Exercise2.cs create mode 100644 Topic1_Arrays/Day2507/Exercise3.cs diff --git a/Topic1_Arrays/.gitignore b/Topic1_Arrays/.gitignore new file mode 100644 index 0000000..345f5fa --- /dev/null +++ b/Topic1_Arrays/.gitignore @@ -0,0 +1,229 @@ +# The following command works for downloading when using Git for Windows: +# curl -LOf http://gist.githubusercontent.com/kmorcinek/2710267/raw/.gitignore +# +# Download this file using PowerShell v3 under Windows with the following comand: +# Invoke-WebRequest https://gist.githubusercontent.com/kmorcinek/2710267/raw/ -OutFile .gitignore +# +# or wget: +# wget --no-check-certificate http://gist.githubusercontent.com/kmorcinek/2710267/raw/.gitignore + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +x64/ +[Bb]in/ +[Oo]bj/ +# build folder is nowadays used for build scripts and should not be ignored +#build/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sln +*.csproj + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings +modulesbin/ +tempbin/ + +# EPiServer Site file (VPP) +AppData/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# vim +*.txt~ +*.swp +*.swo + +# Temp files when opening LibreOffice on ubuntu +.~lock.* + +# svn +.svn + +# CVS - Source Control +**/CVS/ + +# Remainings from resolving conflicts in Source Control +*.orig + +# SQL Server files +**/App_Data/*.mdf +**/App_Data/*.ldf +**/App_Data/*.sdf + + +#LightSwitch generated files +GeneratedArtifacts/ +_Pvt_Extensions/ +ModelManifest.xml + +# ========================= +# Windows detritus +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# OS generated files # +Icon? + +# Mac desktop service store files +.DS_Store + +# SASS Compiler cache +.sass-cache + +# Visual Studio 2014 CTP +**/*.sln.ide + +# Visual Studio temp something +.vs/ + +# dotnet stuff +project.lock.json + +# VS 2015+ +*.vc.vc.opendb +*.vc.db + +# Rider +.idea/ + +# Visual Studio Code +.vscode/ + +# Output folder used by Webpack or other FE stuff +**/node_modules/* +package-lock.json +**/wwwroot/* + +# SpecFlow specific +*.feature.cs +*.feature.xlsx.* +*.Specs_*.html + +# UWP Projects +AppPackages/ + +##### +# End of core ignore list, below put you custom 'per project' settings (patterns or path) +##### diff --git a/Topic1_Arrays/Day2507/Exercise1.cs b/Topic1_Arrays/Day2507/Exercise1.cs new file mode 100644 index 0000000..5991dc1 --- /dev/null +++ b/Topic1_Arrays/Day2507/Exercise1.cs @@ -0,0 +1,48 @@ +//https://leetcode.com/problems/container-with-most-water/description/ + + +/* +Use Two pointers technique ++ I will have 2 pointers at the beginning and at the end ++ For every loop, i will calc the current area => assign it to result if current result is smaller ++ Because max area must have the maximum width and maximum height. Therefore, if current pointer left +is smaller than pointer right, I will move pointer left to right to find bigger height. Converserly, +if current pointer right is smaller than pointer left, I will move pointer right to left to find bigger height ++ Return the result + + +Space complexity: O(1) +Time complexity: O(n) +*/ + + +namespace Day2507 +{ + public class Exercise1 + { + public int MaxArea(int[] arr) + { + int initialLength = arr.Length; + int result = 0; + int left = 0; + int right = initialLength - 1; + + + while(left < right) + { + int width = right - left; + int height = Math.Min(arr[left], arr[right]); + int calcArea = width * height; + + result = Math.Max(result, calcArea); + + if(arr[left] < arr[right]) + ++left; + else + --right; + + } + return result; + } + } +} \ No newline at end of file diff --git a/Topic1_Arrays/Day2507/Exercise2.cs b/Topic1_Arrays/Day2507/Exercise2.cs new file mode 100644 index 0000000..3df90b1 --- /dev/null +++ b/Topic1_Arrays/Day2507/Exercise2.cs @@ -0,0 +1,45 @@ +//https://leetcode.com/problems/subarray-sum-equals-k/description/ + + +/* ++ To store [key, value] ([currentSum, occurence]) in dictionary ++ I will have sum variable to sum all the elements from the beginning to current position ++ At every position, I will find whether key: currentSum - k exists in dictionary or not. If it exists, it means that +there's definetely an subarray equals to sum => plus the occurence of that sum into result ++ To add current sum with occurence equals to 1 into dictionary if current sum doesn't exist. Otherwise, plus the occurence of +that sum one value ++ Return the result + + +Space complexity: O(n) +Time complexity: O(n) +*/ + +namespace Day2507 +{ + public class Exercise2 + { + public int SubarraySum(int[] nums, int k) { + int result = 0; + + Dictionary myDict = new(); + myDict[0] = 1; + + int sum = 0; + + foreach(int num in nums) + { + sum += num; + + if (myDict.ContainsKey(sum - k)) + result += myDict[sum - k]; + + if (!myDict.ContainsKey(sum)) + myDict[sum] = 1; + else + myDict[sum] += 1; + } + return result; + } + } +} \ No newline at end of file diff --git a/Topic1_Arrays/Day2507/Exercise3.cs b/Topic1_Arrays/Day2507/Exercise3.cs new file mode 100644 index 0000000..dcec51b --- /dev/null +++ b/Topic1_Arrays/Day2507/Exercise3.cs @@ -0,0 +1,46 @@ + +//https://leetcode.com/problems/find-common-characters/ + + +/* ++To use character array technique ++ For every word, I will loop every character and increase one value based on current character in charCount array ++ After that, I will compare charCount array with original arr to get min value between these values ++ To loop original array and add valid character in result list ++ Return result + +Space complexity: O(26) +Time complexity: O(n * m) +*/ + + +namespace Day2507 +{ + public class Exercise3 + { + public IList CommonChars(string[] words) { + List result = new(); + + int[] arr = new int[26]; + Array.Fill(arr, int.MaxValue); + + foreach(string word in words) + { + int[] charCount = new int[26]; + + foreach(char character in word) + charCount[character - 'a'] += 1; + + for (int i = 0; i < 26; i++) + arr[i] = Math.Min(arr[i], charCount[i]); + } + + for (int i = 0; i < 26; i++) { + for (int j = 0; j < arr[i]; j++) { + result.Add(((char)(i + 'a')).ToString()); + } + } + return result; + } + } +} \ No newline at end of file From 3acad519de7520749526613e8ae1cfd885fb57c1 Mon Sep 17 00:00:00 2001 From: tai Date: Fri, 26 Jul 2024 18:04:30 +0700 Subject: [PATCH 02/39] tuantai0708 - Day2607 --- Topic1_Arrays/Day2607/Exercise1.cs | 44 ++++++++++++++++++++++++ Topic1_Arrays/Day2607/Exercise2.cs | 55 ++++++++++++++++++++++++++++++ Topic1_Arrays/Day2607/Exercise3.cs | 35 +++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 Topic1_Arrays/Day2607/Exercise1.cs create mode 100644 Topic1_Arrays/Day2607/Exercise2.cs create mode 100644 Topic1_Arrays/Day2607/Exercise3.cs diff --git a/Topic1_Arrays/Day2607/Exercise1.cs b/Topic1_Arrays/Day2607/Exercise1.cs new file mode 100644 index 0000000..6d02202 --- /dev/null +++ b/Topic1_Arrays/Day2607/Exercise1.cs @@ -0,0 +1,44 @@ +//https://leetcode.com/problems/contiguous-array/description/ + + +/* ++ To store [key, value] ([currentSum, position]) in dictionary ++ I will have sum variable to sum all the elements from the beginning to current position. If value is 1, plus 1 otherwise minus 1 ++ At every position, I will find whether key: currentSum exists in dictionary or not. If it exists, it means that +there's definetely a contiguous array => count new result ++ To add current sum with with current position into dictionary if current sum doesn't exist ++ Return the result + +Space complexity: O(n) +Time complexity: O(n) +*/ + + +namespace Day2607 +{ + public class Exercise1 + { + public int FindMaxLength(int[] nums) + { + Dictionary myDict = new(); + myDict[0] = -1; + + int sum = 0; + int result = 0; + int initialLength = nums.Length; + + for (int i = 0; i < initialLength; ++i) + { + sum += nums[i] == 1 ? 1 : -1; + + if (myDict.ContainsKey(sum)) + result = Math.Max(result, i - myDict[sum]); + + if (!myDict.ContainsKey(sum)) + myDict[sum] = i; + } + + return result; + } + } +} \ No newline at end of file diff --git a/Topic1_Arrays/Day2607/Exercise2.cs b/Topic1_Arrays/Day2607/Exercise2.cs new file mode 100644 index 0000000..49d264c --- /dev/null +++ b/Topic1_Arrays/Day2607/Exercise2.cs @@ -0,0 +1,55 @@ +// https://leetcode.com/problems/next-permutation/ + + +/* +Space complexity: O(1) +Time complexity: O(n) +*/ + +namespace Day2607 +{ + public class Exercise2 + { + public void NextPermutation(int[] nums) + { + int initialLength = nums.Length; + if (initialLength == 0 || initialLength == 1) return; + + //Step 1: to loop from the end to find idx1 where nums[i] > nums[i - 1] + int idx1 = -1; + for (int i = initialLength - 2; i >= 0; --i) + { + if (nums[i] < nums[i + 1]) + { + idx1 = i; + break; + } + } + + if (idx1 == -1) + { + Array.Reverse(nums); + return; + } + + //Step 2: to loop from the end to find idx2 where nums[i] > nums[idx1] + int idx2 = -1; + for (int i = initialLength - 1; i >= 0; --i) + { + if (nums[i] > nums[idx1]) + { + idx2 = i; + break; + } + } + + //Step 3: Swap value of idx1 and idx2 + int temp = nums[idx1]; + nums[idx1] = nums[idx2]; + nums[idx2] = temp; + + //Step 4: Reverse array from idx1 + 1 to end + Array.Reverse(nums, idx1 + 1, initialLength - idx1 - 1); + } + } +} \ No newline at end of file diff --git a/Topic1_Arrays/Day2607/Exercise3.cs b/Topic1_Arrays/Day2607/Exercise3.cs new file mode 100644 index 0000000..d704017 --- /dev/null +++ b/Topic1_Arrays/Day2607/Exercise3.cs @@ -0,0 +1,35 @@ +//https://leetcode.com/problems/maximum-subarray/ + +/* ++ To sum up the current value into currentSum variable and compare that to result variable to get maximum value ++ However, if current sum is smaller than 0, reset to 0 ++ Return the result + +Space complexity: O(1) +Time complexity: O(n) +*/ + +namespace Day2607 +{ + public class Exercise3 + { + public int MaxSubArray(int[] nums) + { + int currentSum = 0; + int result = Int32.MinValue; + + foreach (int num in nums) + { + currentSum += num; + result = Math.Max(result, currentSum); + + if (currentSum < 0) + currentSum = 0; + + } + + + return result; + } + } +} \ No newline at end of file From c87f6098a4bb1381e63a83a80c4d6c309bd48f09 Mon Sep 17 00:00:00 2001 From: tai Date: Sat, 27 Jul 2024 09:36:41 +0700 Subject: [PATCH 03/39] tuantai0708 - Day2707 --- Topic1_Arrays/Day2707/Exercise1.cs | 49 ++++++++++++++++++++++++++++++ Topic1_Arrays/Day2707/Exercise2.cs | 47 ++++++++++++++++++++++++++++ Topic1_Arrays/Day2707/Exercise3.cs | 42 +++++++++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 Topic1_Arrays/Day2707/Exercise1.cs create mode 100644 Topic1_Arrays/Day2707/Exercise2.cs create mode 100644 Topic1_Arrays/Day2707/Exercise3.cs diff --git a/Topic1_Arrays/Day2707/Exercise1.cs b/Topic1_Arrays/Day2707/Exercise1.cs new file mode 100644 index 0000000..fd28500 --- /dev/null +++ b/Topic1_Arrays/Day2707/Exercise1.cs @@ -0,0 +1,49 @@ +//https://leetcode.com/problems/longest-consecutive-sequence/ + +/* ++ I will add every element into set ++ For every single element in array, I will check whether it has the previous value or not ++ If there exists that value, I will loop by increasing one value of current value in array. +Every loop, I will continue to check if value after increasing exists in set or not. +If it exists, plus one value. Otherwise, break that loop ++ To get maximum value between that count value and result value + ++ Return the result + +Space complexity: O(n) +Time complexity: O(n) +*/ + +namespace Day2707 +{ + public class Exercise1 + { + public int LongestConsecutive(int[] nums) + { + HashSet set = new(); + int result = 0; + + foreach (int num in nums) + set.Add(num); + + foreach (int num in nums) + { + int candidate = num; + int before = candidate - 1; + + //the start of sequence or this has been already looped before + if (!set.Contains(before)) + { + int count = 0; + + while (set.Contains(candidate++)) + ++count; + + result = Math.Max(result, count); + + } + } + return result; + } + } +} \ No newline at end of file diff --git a/Topic1_Arrays/Day2707/Exercise2.cs b/Topic1_Arrays/Day2707/Exercise2.cs new file mode 100644 index 0000000..a2106e2 --- /dev/null +++ b/Topic1_Arrays/Day2707/Exercise2.cs @@ -0,0 +1,47 @@ +//https://leetcode.com/problems/top-k-frequent-elements/ + +/* ++ I will add every element into dictionary based on its occurence ++ After that, I will add top-k elements into heap with current value based on its occurence. +If occurence is low, it will be dequeued from the minHeap ++ Add everything in minHeap into list array + ++ Return the result + +Space complexity: O(n^2) +Time complexity: O(klogn) (k is required in parameters) +*/ + +namespace Day2707 +{ + public class Exercise2 + { + public int[] TopKFrequent(int[] nums, int k) + { + Dictionary myDict = new(); + PriorityQueue minHeap = new(); + + foreach (int num in nums) + { + if (myDict.ContainsKey(num)) + myDict[num]++; + else + myDict[num] = 1; + } + + foreach (var kvp in myDict) + { + minHeap.Enqueue(kvp.Key, kvp.Value); + + if (minHeap.Count > k) + minHeap.Dequeue(); + } + + List list = new(); + while (minHeap.Count > 0) + list.Add(minHeap.Dequeue()); + + return list.ToArray(); + } + } +} \ No newline at end of file diff --git a/Topic1_Arrays/Day2707/Exercise3.cs b/Topic1_Arrays/Day2707/Exercise3.cs new file mode 100644 index 0000000..25bbdce --- /dev/null +++ b/Topic1_Arrays/Day2707/Exercise3.cs @@ -0,0 +1,42 @@ +//https://leetcode.com/problems/majority-element/ + +/* ++ I will have the candidate variable to compare it to current value in array ++ if candidate equals to currentValue => plus one value into count variable ++ Otherwise, minus 1. If count equals to 0, change value of candidate variable to current value ++ Return the result + +Space complexity: O(1) +Time complexity: O(n) +*/ +namespace Day2707 +{ + public class Exercise3 + { + public int MajorityElement(int[] nums) + { + int length = nums.Length; + if (length == 1) return nums[0]; + + int candidate = nums[0]; + int count = 1; + + for (int i = 1; i < length; ++i) + { + if (candidate == nums[i]) + ++count; + else + { + --count; + if (count == 0) + { + count = 1; + candidate = nums[i]; + } + } + } + + return candidate; + } + } +} \ No newline at end of file From e273ba2af5acdf9564a16663aa394c918d1262b4 Mon Sep 17 00:00:00 2001 From: tai Date: Sun, 28 Jul 2024 12:03:25 +0700 Subject: [PATCH 04/39] tuantai0708 - Day2807 --- Topic1_Arrays/Day2807/Exercise1.cs | 58 ++++++++++++++++++++++++++++++ Topic1_Arrays/Day2807/Exercise2.cs | 46 ++++++++++++++++++++++++ Topic1_Arrays/Day2807/Exercise3.cs | 50 ++++++++++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 Topic1_Arrays/Day2807/Exercise1.cs create mode 100644 Topic1_Arrays/Day2807/Exercise2.cs create mode 100644 Topic1_Arrays/Day2807/Exercise3.cs diff --git a/Topic1_Arrays/Day2807/Exercise1.cs b/Topic1_Arrays/Day2807/Exercise1.cs new file mode 100644 index 0000000..4efb862 --- /dev/null +++ b/Topic1_Arrays/Day2807/Exercise1.cs @@ -0,0 +1,58 @@ +//https://leetcode.com/problems/bag-of-tokens/ + +/* +Using 2 pointers technique ++ Sort array first ++ For every single loop, there are 3 conditions + + If current value on left <= power => increase one score, minus power, + plus one left, and compare to result variable to get maximum value + + + if score is at least 1 => decrease one score, plus power, + minus one right + + + Otherwise, break (doesn't satisfy 2 previos conditions) + ++ Return the result + +Space complexity: O(1) +Time complexity: O(nlogn) +*/ + +namespace Day2807 +{ + public class Exercise1 + { + public int BagOfTokensScore(int[] tokens, int power) + { + int score = 0; + int result = 0; + int left = 0; + int right = tokens.Length - 1; + + Array.Sort(tokens); + + while (left <= right) + { + if (tokens[left] <= power) + { + power -= tokens[left]; + ++score; + ++left; + result = Math.Max(result, score); + } + else if (score >= 1) + { + power += tokens[right]; + --score; + --right; + } + else + { + break; + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/Topic1_Arrays/Day2807/Exercise2.cs b/Topic1_Arrays/Day2807/Exercise2.cs new file mode 100644 index 0000000..5368926 --- /dev/null +++ b/Topic1_Arrays/Day2807/Exercise2.cs @@ -0,0 +1,46 @@ +//https://leetcode.com/problems/continuous-subarray-sum/ + +/* +Using hashmap technique ++ Adding remainder 0 at idx -1 ++ In hashmap, I will store [remainder, index] + + Store remainder: if remainder already exists => there's definintely good array + For example: + 23,2,4,6,7 k = 6 + i = 0 => 23 % 6 = 5 + i = 0 => 25 % 6 = 1 + i = 0 => 29 % 6 = 5 + => This remainder already exists => good array [2, 4] + + Store index: to ensure that there are at least 2 elements + +Space complexity: O(n) +Time complexity: O(n) +*/ +namespace Day2807 +{ + public class Exercise2 + { + public bool CheckSubarraySum(int[] nums, int k) + { + Dictionary myDictionary = new(); + myDictionary[0] = -1; + + int length = nums.Length; + + int sum = 0; + for (int i = 0; i < length; ++i) + { + sum += nums[i]; + int count = sum % k; + + if (!myDictionary.ContainsKey(count)) + myDictionary[count] = i; + else if (i - myDictionary[count] >= 2) + return true; + + } + + return false; + } + } +} \ No newline at end of file diff --git a/Topic1_Arrays/Day2807/Exercise3.cs b/Topic1_Arrays/Day2807/Exercise3.cs new file mode 100644 index 0000000..3016a18 --- /dev/null +++ b/Topic1_Arrays/Day2807/Exercise3.cs @@ -0,0 +1,50 @@ +//https://leetcode.com/problems/reveal-cards-in-increasing-order/ + +/* +Using queue technique ++ To sort array ++ To initialize Queue to store idx from 0 => length - 1 of deck array ++ When looping array deck, get current idx in Queue and assign current value of card into value at idx of result ++ If there still exists any indices in Queue, dequeue and add it to the end of Queue + ++ Return result + + +Space complexity: O(n) +Time complexity: O(nlogn) +*/ + +namespace Day2807 +{ + public class Exercise3 + { + public int[] DeckRevealedIncreasing(int[] deck) + { + // Sort the deck + Array.Sort(deck); + + // Initialize a queue to store the indices + // Indices is a list of idx of deck array + Queue indices = new Queue(Enumerable.Range(0, deck.Length)); + + // Initialize the result array + int[] result = new int[deck.Length]; + + // Iterate over sorted deck and populate result array + foreach (var card in deck) + { + // Take the index of the next unrevealed card + int idx = indices.Dequeue(); + // Assign the revealed card to the correct position + result[idx] = card; + + // If there are still unrevealed cards, move the next unrevealed card to the end + if (indices.Count > 0) + indices.Enqueue(indices.Dequeue()); + + } + + return result; + } + } +} \ No newline at end of file From a9bb88476ba05720adf7f86682bd53f95d67f438 Mon Sep 17 00:00:00 2001 From: tai Date: Tue, 30 Jul 2024 21:36:20 +0700 Subject: [PATCH 05/39] tuantai0708 - Day2307 --- Topic1_Arrays/Day2307/Exercise1.cs | 62 ++++++++++++++++++++++++++++++ Topic1_Arrays/Day2307/Exercise2.cs | 52 +++++++++++++++++++++++++ Topic1_Arrays/Day2307/Exercise3.cs | 37 ++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 Topic1_Arrays/Day2307/Exercise1.cs create mode 100644 Topic1_Arrays/Day2307/Exercise2.cs create mode 100644 Topic1_Arrays/Day2307/Exercise3.cs diff --git a/Topic1_Arrays/Day2307/Exercise1.cs b/Topic1_Arrays/Day2307/Exercise1.cs new file mode 100644 index 0000000..6bc04da --- /dev/null +++ b/Topic1_Arrays/Day2307/Exercise1.cs @@ -0,0 +1,62 @@ +//https://leetcode.com/problems/random-pick-with-weight/description/ + +/* ++ To use Binary Search technique ++ To calculate sum of the array ++ To build array where each value will show the range between [0, 1] + + For example: + [1, 3, 2, 4] + sum = 10 + [0.1, 0.4, 0.6, 1.0] ++ To find idx using Binary search. + + If current value is smaller than randomNumber => left = mid + 1; + + Otherwise => right = mid + ++ Return left idx + +Space complexity: O(n) +Time complexity: O(n) +*/ + +namespace Day2307 +{ + public class Solution + { + private double[] weights; + private int _sum = 0; + private Random random = new Random(); + + public Solution(int[] w) + { + weights = new double[w.Length]; + _sum = w.Sum(); + + int prevSum = 0; + for (int i = 0; i < w.Length; ++i) + { + prevSum += w[i]; + weights[i] = prevSum * 1.0 / _sum; + } + } + + public int PickIndex() + { + double randomNumber = random.NextDouble(); + + int left = 0; + int right = weights.Length - 1; + + while (left < right) + { + int mid = left + (right - left) / 2; + + if (weights[mid] < randomNumber) + left = mid + 1; + else + right = mid; + } + + return left; + } + } +} \ No newline at end of file diff --git a/Topic1_Arrays/Day2307/Exercise2.cs b/Topic1_Arrays/Day2307/Exercise2.cs new file mode 100644 index 0000000..884e749 --- /dev/null +++ b/Topic1_Arrays/Day2307/Exercise2.cs @@ -0,0 +1,52 @@ +//https://leetcode.com/problems/merge-intervals/ + +/* ++ To sort 2d array based on idx 0 ++ We will create 2 variables: "start", and "end" to compare ++ For every single element, I will compare "start" and "end" value at idx i to "start" and "end" of temp variables + + if there is overlapping => update "start" and "end" of temp variables + + if there is no-overlapping => add to list, and update "start" and "end" of temp variables to "start" and "end" of current idx +Space complexity: O(1) +Time complexity: O(nlogn) +*/ + +namespace Day2307 +{ + public class Exercise2 + { + public int[][] Merge(int[][] intervals) + { + List listAns = new(); + + if (intervals.Length == 1) + return intervals; + + //Sort based on value of start idx + Array.Sort(intervals, (x, y) => x[0].CompareTo(y[0])); + + int startValue = intervals[0][0]; + int endValue = intervals[0][1]; + + for (int i = 1; i < intervals.Length; ++i) + { + //overlapping + if (startValue <= intervals[i][0] && intervals[i][0] <= endValue) + { + startValue = Math.Min(startValue, intervals[i][0]); + endValue = Math.Max(endValue, intervals[i][1]); + } + //non-overlapping + else + { + listAns.Add([startValue, endValue]); + startValue = intervals[i][0]; + endValue = intervals[i][1]; + } + } + + listAns.Add([startValue, endValue]); + + return listAns.ToArray(); + } + } +} \ No newline at end of file diff --git a/Topic1_Arrays/Day2307/Exercise3.cs b/Topic1_Arrays/Day2307/Exercise3.cs new file mode 100644 index 0000000..61e114e --- /dev/null +++ b/Topic1_Arrays/Day2307/Exercise3.cs @@ -0,0 +1,37 @@ +//https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ + +/* ++ To choose the time to buy is at idx 0 ++ From idx 1 to end + + Always count the profit => if cur profit is larger than result => update result + + if the time to buy is smaller than cur value => update buy time + +Space complexity: O(1) +Time complexity: O(n) +*/ + +namespace Day2307 +{ + public class Exercise3 + { + public int MaxProfit(int[] prices) + { + int result = 0; + int length = prices.Length; + + if (length == 1) return result; + + int buy = prices[0]; + + foreach (int price in prices) + { + int count = price - buy; + + result = Math.Max(result, count); + buy = Math.Min(buy, price); + } + + return result; + } + } +} \ No newline at end of file From 91181fb299879bb189ec30f51197b95ec6baedbb Mon Sep 17 00:00:00 2001 From: tai Date: Wed, 31 Jul 2024 20:59:18 +0700 Subject: [PATCH 06/39] tuantai0708 - Day2407 --- Topic1_Arrays/Day2407/Exercise1.cs | 51 +++++++++++++++++++++++ Topic1_Arrays/Day2407/Exercise2.cs | 43 ++++++++++++++++++++ Topic1_Arrays/Day2407/Exercise3.cs | 65 ++++++++++++++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 Topic1_Arrays/Day2407/Exercise1.cs create mode 100644 Topic1_Arrays/Day2407/Exercise2.cs create mode 100644 Topic1_Arrays/Day2407/Exercise3.cs diff --git a/Topic1_Arrays/Day2407/Exercise1.cs b/Topic1_Arrays/Day2407/Exercise1.cs new file mode 100644 index 0000000..3ab2616 --- /dev/null +++ b/Topic1_Arrays/Day2407/Exercise1.cs @@ -0,0 +1,51 @@ +//https://leetcode.com/problems/group-anagrams/ + +/* ++ To store dictionary + + Key: character and its occurence in array + + Value: string with the same group anagram + ++ To loop every string in list string + + for every string, we will build string with every character in string of array and its occurence + + After building string + + If string already exists in dictionary => add into dictionary with that key + + If string doesn't exist in dictionary => add new key and value in dictionary + +Space complexity: O(n) +Time complexity: O(n * (m + 26)) +*/ + +namespace Day2407 +{ + public class Exercise1 + { + public IList> GroupAnagrams(string[] strs) + { + Dictionary> myDict = new(); + + foreach (string str in strs) + { + int[] countChar = new int[26]; + foreach (char c in str) + countChar[c - 'a']++; + + string temp = ""; + for (int i = 0; i < 26; ++i) + { + if (countChar[i] != 0) + { + temp += countChar[i]; + temp += (char)('a' + i); + } + } + + if (myDict.ContainsKey(temp)) + myDict[temp].Add(str); + else + myDict[temp] = new List { str }; + } + + return new List>(myDict.Values); + } + } +} \ No newline at end of file diff --git a/Topic1_Arrays/Day2407/Exercise2.cs b/Topic1_Arrays/Day2407/Exercise2.cs new file mode 100644 index 0000000..e9c475b --- /dev/null +++ b/Topic1_Arrays/Day2407/Exercise2.cs @@ -0,0 +1,43 @@ +//https://leetcode.com/problems/kth-largest-element-in-an-array/ + +/* ++ To store PriorityQueue ++ This PriorityQueue stores k elements from small to biggest ++ When looping every number + + If PriorityQueue doesn't have enough k elements => add + + If PriorityQueue has enough k elements => and if peek of + PriorityQueue is smaller than current value + => deuqueue to remove smallest element in PriorityQueue and add a new value ++ Return the peek of PriorityQueue + +Space complexity: O(n) +Time complexity: O(n * klogn) +*/ + +namespace Day2407 +{ + public class Exercise2 + { + public int FindKthLargest(int[] nums, int k) + { + PriorityQueue priorityQueue = new(); + + foreach (int num in nums) + { + if (priorityQueue.Count < k) + priorityQueue.Enqueue(num, num); + else + { + if (priorityQueue.Peek() < num) + { + priorityQueue.Dequeue(); + priorityQueue.Enqueue(num, num); + } + + } + } + + return priorityQueue.Peek(); + } + } +} \ No newline at end of file diff --git a/Topic1_Arrays/Day2407/Exercise3.cs b/Topic1_Arrays/Day2407/Exercise3.cs new file mode 100644 index 0000000..76aa895 --- /dev/null +++ b/Topic1_Arrays/Day2407/Exercise3.cs @@ -0,0 +1,65 @@ +//https://leetcode.com/problems/3sum/ + +/* ++ To sort Array first ++ When looping every element, we will ignore duplicate values, and count 3sum + + First element: current element + + Second element: element next to first element + + Third element: element at the end ++ if sum is 0 => add to result list and move left, and right pointer to valid position (ignore duplicate values) + ++ Return result + +Space complexity: O(1) +Time complexity: O(n2) +*/ + +namespace Day2407 +{ + public class Exercise3 + { + public IList> ThreeSum(int[] nums) + { + Array.Sort(nums); + + IList> result = new List>(); + + int length = nums.Length; + for (int i = 0; i < length - 2; ++i) + { + //ignore duplicate values + if (i > 0 && nums[i] == nums[i - 1]) + continue; + + int left = i + 1; + int right = length - 1; + + while (left < right) + { + int threeSum = nums[i] + nums[left] + nums[right]; + + if (threeSum > 0) + --right; + else if (threeSum < 0) + ++left; + else + { + result.Add(new List { nums[i], nums[left], nums[right] }); + + ++left; + --right; + + while (nums[left] == nums[left - 1] && left < right) + ++left; + + while (nums[right] == nums[right + 1] && left < right) + --right; + + } + } + } + + return result; + } + } +} \ No newline at end of file From 687b42733994c2be18cbe730f8bf4c98e7c9e167 Mon Sep 17 00:00:00 2001 From: tai Date: Thu, 1 Aug 2024 19:23:33 +0700 Subject: [PATCH 07/39] tuantai0708 - Day2207 --- Topic1_Arrays/Day2207/Exercise1.cs | 43 ++++++++++++++++++++++++ Topic1_Arrays/Day2207/Exercise2.cs | 52 ++++++++++++++++++++++++++++++ Topic1_Arrays/Day2207/Exercise3.cs | 36 +++++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 Topic1_Arrays/Day2207/Exercise1.cs create mode 100644 Topic1_Arrays/Day2207/Exercise2.cs create mode 100644 Topic1_Arrays/Day2207/Exercise3.cs diff --git a/Topic1_Arrays/Day2207/Exercise1.cs b/Topic1_Arrays/Day2207/Exercise1.cs new file mode 100644 index 0000000..181d36f --- /dev/null +++ b/Topic1_Arrays/Day2207/Exercise1.cs @@ -0,0 +1,43 @@ +//https://leetcode.com/problems/two-sum/submissions/1340665663/ + +/* ++ To use Dictionary + + Key: current value + + Value: idx of its ++ When looping every single element, I need to get target minus current value to find +whether that value exists in dictionary or not + + If it doesn't exist => add to dictionary + + If it exists => add to result array to return + +Space complexity: O(n) +Time complexity: O(n) +*/ + +namespace Day2207 +{ + public class Exercise1 + { + public int[] TwoSum(int[] nums, int target) + { + Dictionary myDict = new(); + + int[] result = new int[2]; + + for (int i = 0; i < nums.Length; ++i) + { + int calc = target - nums[i]; + if (myDict.ContainsKey(calc)) + { + result[0] = myDict[calc]; + result[1] = i; + break; + + } + else + myDict[nums[i]] = i; + } + + return result; + } + } +} \ No newline at end of file diff --git a/Topic1_Arrays/Day2207/Exercise2.cs b/Topic1_Arrays/Day2207/Exercise2.cs new file mode 100644 index 0000000..c48a563 --- /dev/null +++ b/Topic1_Arrays/Day2207/Exercise2.cs @@ -0,0 +1,52 @@ +//https://leetcode.com/problems/number-of-islands/description/ + +/* ++ To use recursion technique ++ I will loop every single element in 2d arrays ++ If current value is '1' => not visited => backtracking that position and plus 1 value of result ++ When backtracking current position, mark its neightbor values as '2' (islands but visited) + +Space complexity: O(n^2) +Time complexity: O(1) +*/ + +namespace Day2207 +{ + public class Exercise2 + { + public int NumIslands(char[][] grid) + { + int row = grid.Length; + int col = grid[0].Length; + + int result = 0; + + for (int i = 0; i < row; ++i) + { + for (int j = 0; j < col; ++j) + { + if (grid[i][j] == '1') + { + ++result; + Backtrack(grid, i, j, row, col); + } + } + } + + return result; + } + + private void Backtrack(char[][] grid, int i, int j, int m, int n) + { + if (i < 0 || i == m || j < 0 || j == n || grid[i][j] != '1') + return; + + grid[i][j] = '2'; // visited + + Backtrack(grid, i - 1, j, m, n); + Backtrack(grid, i, j - 1, m, n); + Backtrack(grid, i + 1, j, m, n); + Backtrack(grid, i, j + 1, m, n); + } + } +} \ No newline at end of file diff --git a/Topic1_Arrays/Day2207/Exercise3.cs b/Topic1_Arrays/Day2207/Exercise3.cs new file mode 100644 index 0000000..1f9cb2c --- /dev/null +++ b/Topic1_Arrays/Day2207/Exercise3.cs @@ -0,0 +1,36 @@ +//https://leetcode.com/problems/merge-sorted-array/ + +/* ++ I will have 2 pointers at the end of every array ++ when comparing 2 current values in array, I need to move larger value into the end of array ++ Fill all remaining values of nums2 array into nums1 array + +Space complexity: O(m + n) +Time complexity: O(1) +*/ + +namespace Day2207 +{ + public class Exercise3 + { + public void Merge(int[] nums1, int m, int[] nums2, int n) + { + int i = m - 1; + int j = n - 1; + int k = nums1.Length - 1; + + while (i >= 0 && j >= 0) + { + if (nums1[i] >= nums2[j]) + nums1[k--] = nums1[i--]; + else + nums1[k--] = nums2[j--]; + } + + + //fill all remaining elements in nums2 array into nums1 array + while (j >= 0) + nums1[k--] = nums2[j--]; + } + } +} \ No newline at end of file From 0764324d033be88c8549904d5416672931b8e131 Mon Sep 17 00:00:00 2001 From: tai Date: Mon, 5 Aug 2024 10:08:36 +0700 Subject: [PATCH 08/39] tuantai0708 - Day0508 --- Topic1_Arrays/.gitignore => .gitignore | 0 Topic2_LinkedList/Day0508/Exercise1.cs | 47 +++++++++++++++++++++++ Topic2_LinkedList/Day0508/Exercise2.cs | 52 ++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) rename Topic1_Arrays/.gitignore => .gitignore (100%) create mode 100644 Topic2_LinkedList/Day0508/Exercise1.cs create mode 100644 Topic2_LinkedList/Day0508/Exercise2.cs diff --git a/Topic1_Arrays/.gitignore b/.gitignore similarity index 100% rename from Topic1_Arrays/.gitignore rename to .gitignore diff --git a/Topic2_LinkedList/Day0508/Exercise1.cs b/Topic2_LinkedList/Day0508/Exercise1.cs new file mode 100644 index 0000000..041878c --- /dev/null +++ b/Topic2_LinkedList/Day0508/Exercise1.cs @@ -0,0 +1,47 @@ +//https://leetcode.com/problems/reverse-linked-list/ + +/* ++ To use Adding Element at the beginning of Linked list ++ When looping every element, the current element will be added at the beginning + +Space complexity: O(1) +Time complexity: O(n) +*/ + +namespace Day0508 +{ + // Definition for singly-linked list. + public class ListNode + { + public int val; + public ListNode next; + public ListNode(int val = 0, ListNode next = null) + { + this.val = val; + this.next = next; + } + } + public class Exercise1 + { + public ListNode ReverseList(ListNode head) + { + if (head == null || head.next == null) return head; + + ListNode prev = new(-1); + ListNode cur = head; + + while (cur != null) + { + ListNode next = cur.next; + ListNode nextPrev = prev.next; + + prev.next = cur; + cur.next = nextPrev; + + cur = next; + + } + return prev.next; + } + } +} \ No newline at end of file diff --git a/Topic2_LinkedList/Day0508/Exercise2.cs b/Topic2_LinkedList/Day0508/Exercise2.cs new file mode 100644 index 0000000..56cfb8b --- /dev/null +++ b/Topic2_LinkedList/Day0508/Exercise2.cs @@ -0,0 +1,52 @@ +//https://leetcode.com/problems/merge-two-sorted-lists/ + +/* ++ To use two pointer technique ++ Looping list1 and list2 until 2 lists are totally null + + If cur val of any lists is not null + => get current value + + Otherwise + => assign it to Max int + + + if val of list1 is smaller or equals val of list2 + => add current pointer of list1 into result + => move list1 to next pointer + + Otherwise + => add current pointer of list2 into result + => move list2 to next pointer + +Space complexity: O(1) +Time complexity: O(Max(m, n)): m is length of list1 and n is lengh of list2 +*/ + +namespace Day0508 +{ + public class Exercise2 + { + public ListNode MergeTwoLists(ListNode list1, ListNode list2) + { + ListNode dummyNode = new(-1); + ListNode result = dummyNode; + + while (list1 != null || list2 != null) + { + int val1 = list1 != null ? list1.val : int.MaxValue; + int val2 = list2 != null ? list2.val : int.MaxValue; + + if (val1 <= val2) + { + dummyNode.next = list1; + list1 = list1.next; + } + else + { + dummyNode.next = list2; + list2 = list2.next; + } + dummyNode = dummyNode.next; + } + + return result.next; + } + } +} \ No newline at end of file From bad073d4a184ecf9e8f33c187b3d86e55614f232 Mon Sep 17 00:00:00 2001 From: tai Date: Tue, 6 Aug 2024 10:48:23 +0700 Subject: [PATCH 09/39] tuantai0708 - Day0608 --- Topic2_LinkedList/Day0608/Exercise1.cs | 86 ++++++++++++++++++++++++++ Topic2_LinkedList/Day0608/Exercise2.cs | 46 ++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 Topic2_LinkedList/Day0608/Exercise1.cs create mode 100644 Topic2_LinkedList/Day0608/Exercise2.cs diff --git a/Topic2_LinkedList/Day0608/Exercise1.cs b/Topic2_LinkedList/Day0608/Exercise1.cs new file mode 100644 index 0000000..5e72b3c --- /dev/null +++ b/Topic2_LinkedList/Day0608/Exercise1.cs @@ -0,0 +1,86 @@ +// /https://leetcode.com/problems/reorder-list/description/ + +/* ++ Step 1: to place slow and fast pointers at right position ++ Step 2: reverse list from the fast pointer to the end ++ Step 3: merge 2 lists + +Space complexity: O(1) +Time complexity: O(n): +*/ + +namespace Day0608 +{ + // Definition for singly-linked list. + public class ListNode + { + public int val; + public ListNode next; + public ListNode(int val = 0, ListNode next = null) + { + this.val = val; + this.next = next; + } + } + + public class Exercise1 + { + public void ReorderList(ListNode head) + { + //move slow and fast pointers to the right position + ListNode slow = head; + ListNode fast = head.next; + + while (slow != null && fast != null && fast.next != null) + { + slow = slow.next; + fast = fast.next.next; + } + + //reverse second half of the list + ListNode first = head; + ListNode second = ReverseList(slow.next); + slow.next = null; + + //merge 2 lists into first pointer + Merge(first, second); + + } + + private ListNode ReverseList(ListNode head) + { + ListNode prev = null; + + ListNode cur = head; + + while (cur != null) + { + ListNode next = cur.next; + + cur.next = prev; + prev = cur; + cur = next; + } + + return prev; + } + + private void Merge(ListNode first, ListNode second) + { + while (first != null) + { + ListNode firstNext = first.next; + ListNode secondNext = second != null ? second.next : null; + + first.next = second; + + if (firstNext == null) return; + + second.next = firstNext; + + first = firstNext; + second = secondNext; + } + } + } +} \ No newline at end of file diff --git a/Topic2_LinkedList/Day0608/Exercise2.cs b/Topic2_LinkedList/Day0608/Exercise2.cs new file mode 100644 index 0000000..a61886f --- /dev/null +++ b/Topic2_LinkedList/Day0608/Exercise2.cs @@ -0,0 +1,46 @@ +//https://leetcode.com/problems/remove-nth-node-from-end-of-list/ + +/* ++ To add dummyNode at the beginning of head ++ We will have 2 pointers + + First: at dumymNode + + Second: at head ++ We will move second pointer first within n times + + If second pointer is null => remove the first element ++ And move second pointer until it reachs null of head, along with first pointer ++ Update first pointer + +Space complexity: O(1) +Time complexity: O(n): +*/ + +namespace Day0608 +{ + public class Exercise2 + { + public ListNode RemoveNthFromEnd(ListNode head, int n) + { + ListNode dummyNode = new(-1); + dummyNode.next = head; + + ListNode first = dummyNode; + ListNode second = head; + + for (int i = 1; i <= n; ++i) + second = second.next; + + if (second == null) return head.next; + + while (second != null) + { + first = first.next; + second = second.next; + } + + first.next = first.next.next; + + return dummyNode.next; + + } + } +} \ No newline at end of file From fd9700032351057cedbe758df39471c9263f64b8 Mon Sep 17 00:00:00 2001 From: tai Date: Wed, 7 Aug 2024 10:40:50 +0700 Subject: [PATCH 10/39] tuantai0708 - Day0708 --- Topic2_LinkedList/Day0708/Exercise1.cs | 62 ++++++++++++++++++++++++++ Topic2_LinkedList/Day0708/Exercise2.cs | 62 ++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 Topic2_LinkedList/Day0708/Exercise1.cs create mode 100644 Topic2_LinkedList/Day0708/Exercise2.cs diff --git a/Topic2_LinkedList/Day0708/Exercise1.cs b/Topic2_LinkedList/Day0708/Exercise1.cs new file mode 100644 index 0000000..eddcf8d --- /dev/null +++ b/Topic2_LinkedList/Day0708/Exercise1.cs @@ -0,0 +1,62 @@ +//https://leetcode.com/problems/copy-list-with-random-pointer/ + +/* ++ To use 2 loops + + Loop 1: To build dictionary + + Key: current Node + + value: new Node + + Loop 2: To build list + + To loop defined head list and assign next and random pointer for current Node + +Space complexity: O(n) +Time complexity: O(n): +*/ + +namespace Day0708 +{ + public class Exercise1 + { + public class Node + { + public int val; + public Node next; + public Node random; + public Node(int val = 0, Node next = null, Node random = null) + { + this.val = val; + this.next = next; + this.random = random; + } + } + public Node CopyRandomList(Node head) + { + Dictionary myDict = new(); + Node temp = head; + + while (temp != null) + { + //to create a new node, instead of using current node + myDict[temp] = new Node(temp.val); + temp = temp.next; + } + + Node dummyNode = new(-1); + Node result = dummyNode; + temp = head; + + while (temp != null) + { + Node copyNode = myDict[temp]; + copyNode.next = temp.next != null ? myDict[temp.next] : null; + copyNode.random = temp.random != null ? myDict[temp.random] : null; + + dummyNode.next = copyNode; + + dummyNode = dummyNode.next; + temp = temp.next; + } + + return result.next; + } + } +} \ No newline at end of file diff --git a/Topic2_LinkedList/Day0708/Exercise2.cs b/Topic2_LinkedList/Day0708/Exercise2.cs new file mode 100644 index 0000000..e505688 --- /dev/null +++ b/Topic2_LinkedList/Day0708/Exercise2.cs @@ -0,0 +1,62 @@ +//https://leetcode.com/problems/add-two-numbers/ + +/* ++ We will have 2 pointers when looping 2 lists + + If current pointer is not null => get current value + + Otherwise, assign to 0 ++ Create node after adding 2 values and leftOver => get remaining ++ Calc leftOver by getting that value / 10 + ++ At the end, I must check if leftOver equals 0 or not + + If it doesn't equal 0 => adding that value to result + +Space complexity: O(1) +Time complexity: O(n): +*/ +namespace Day0708 +{ + public class Exercise2 + { + public class ListNode + { + public int val; + public ListNode next; + public ListNode(int val = 0, ListNode next = null) + { + this.val = val; + this.next = next; + } + } + + public ListNode AddTwoNumbers(ListNode l1, ListNode l2) + { + int leftOver = 0; + ListNode dummyNode = new(-1); + ListNode result = dummyNode; + + while (l1 != null || l2 != null) + { + int val1 = l1 != null ? l1.val : 0; + int val2 = l2 != null ? l2.val : 0; + + int val = val1 + val2 + leftOver; + + dummyNode.next = new ListNode(val % 10); + dummyNode = dummyNode.next; + + leftOver = val / 10; + + if (l1 != null) l1 = l1.next; + if (l2 != null) l2 = l2.next; + } + + if (leftOver != 0) + { + dummyNode.next = new ListNode(leftOver); + dummyNode = dummyNode.next; + } + + return result.next; + } + } +} \ No newline at end of file From 08b3a5661a769ac929a06213e431d8a22beb7cbf Mon Sep 17 00:00:00 2001 From: tai Date: Thu, 8 Aug 2024 07:19:05 +0700 Subject: [PATCH 11/39] tuantai0708 - Day0808 --- Topic2_LinkedList/Day0808/Exercise1.cs | 44 ++++++++++++++++++++ Topic2_LinkedList/Day0808/Exercise2.cs | 56 ++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 Topic2_LinkedList/Day0808/Exercise1.cs create mode 100644 Topic2_LinkedList/Day0808/Exercise2.cs diff --git a/Topic2_LinkedList/Day0808/Exercise1.cs b/Topic2_LinkedList/Day0808/Exercise1.cs new file mode 100644 index 0000000..8424fdc --- /dev/null +++ b/Topic2_LinkedList/Day0808/Exercise1.cs @@ -0,0 +1,44 @@ +//https://leetcode.com/problems/linked-list-cycle/ + +/* ++ To use slow and fast pointer technique + + slow: move forward one position + + fast: move forward two positions ++ If slow and fast meet together => a cycle + +Space complexity: O(1) +Time complexity: O(n): +*/ + +namespace Day0808 +{ + public class Exercise1 + { + public class ListNode + { + public int val; + public ListNode next; + public ListNode(int val = 0, ListNode next = null) + { + this.val = val; + this.next = next; + } + } + public bool HasCycle(ListNode head) + { + if (head == null || head.next == null) return false; + + ListNode slow = head; + ListNode fast = head.next; + + while (slow != null && fast != null && fast.next != null) + { + slow = slow.next; + fast = fast.next.next; + + if (slow == fast) return true; + } + return false; + } + } +} \ No newline at end of file diff --git a/Topic2_LinkedList/Day0808/Exercise2.cs b/Topic2_LinkedList/Day0808/Exercise2.cs new file mode 100644 index 0000000..82737c0 --- /dev/null +++ b/Topic2_LinkedList/Day0808/Exercise2.cs @@ -0,0 +1,56 @@ +// https://leetcode.com/problems/linked-list-cycle-ii/ + +/* ++ To use slow and fast pointer technique + + slow: move forward one position + + fast: move forward two positions ++ If slow and fast meet together => a cycle + + If there is a cycle, I will have the pointer at the beginning + + This pointer and slow pointer will move forward one position until it reachs + => A position where a cycle starts ++ There is not a cycle + +Space complexity: O(1) +Time complexity: O(n): +*/ +namespace Day0808 +{ + public class Exercise2 + { + public class ListNode + { + public int val; + public ListNode next; + public ListNode(int val = 0, ListNode next = null) + { + this.val = val; + this.next = next; + } + } + public ListNode DetectCycle(ListNode head) + { + if (head == null || head.next == null) return null; + + ListNode begin = head; + ListNode slow = head; + ListNode fast = head; + + while (slow != null && fast != null && fast.next != null) + { + slow = slow.next; + fast = fast.next.next; + + if (slow == fast) + { + while (begin != slow) + { + begin = begin.next; + slow = slow.next; + } + return begin; + } + } + return null; + } + } +} \ No newline at end of file From 1a7a9c1e1c65117a12ab7fc3089128de66ff95c8 Mon Sep 17 00:00:00 2001 From: tai Date: Fri, 9 Aug 2024 07:37:05 +0700 Subject: [PATCH 12/39] tuantai0708 - Day0908 --- Topic2_LinkedList/Day0908/Exercise1.cs | 52 +++++++++++++++++ Topic2_LinkedList/Day0908/Exercise2.cs | 80 ++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 Topic2_LinkedList/Day0908/Exercise1.cs create mode 100644 Topic2_LinkedList/Day0908/Exercise2.cs diff --git a/Topic2_LinkedList/Day0908/Exercise1.cs b/Topic2_LinkedList/Day0908/Exercise1.cs new file mode 100644 index 0000000..44de46f --- /dev/null +++ b/Topic2_LinkedList/Day0908/Exercise1.cs @@ -0,0 +1,52 @@ +//https://leetcode.com/problems/happy-number/ + +/* ++ To use slow and fast pointer technique in Linked List + + slow: to count number at slow position + + fasst: to count number at fast position ++ If slow and fast pointers meet together and it doesn't meet at 1 value => a cycle => return false ++ return true; + +Space complexity: O(1) +Time complexity: O(n): +*/ + +namespace Day0908 +{ + public class Exercise1 + { + public bool IsHappy(int n) + { + if (n == 1) + return true; + + int slow = n; + int fast = n; + + while (fast != 1) + { + slow = _countNumber(slow); + fast = _countNumber(_countNumber(fast)); + + //if there is a cycle not at 1 + if (slow == fast && fast != 1) + return false; + + } + + return true; + } + + private int _countNumber(int n) + { + int result = 0; + while (n != 0) + { + result += (int)Math.Pow(n % 10, 2.0); + n /= 10; + } + + return result; + } + } +} \ No newline at end of file diff --git a/Topic2_LinkedList/Day0908/Exercise2.cs b/Topic2_LinkedList/Day0908/Exercise2.cs new file mode 100644 index 0000000..30937b2 --- /dev/null +++ b/Topic2_LinkedList/Day0908/Exercise2.cs @@ -0,0 +1,80 @@ +//https://leetcode.com/problems/palindrome-linked-list/description/ + +/* ++ To use slow and fast pointer technique in Linked List ++ To reverse Linked List at slow pointer ++ To compare 2 values at begin and slow pointer + => if it's different => false + ++ return true; + +Space complexity: O(1) +Time complexity: O(n) +*/ + +namespace Day0908 +{ + public class Exercise2 + { + // Definition for singly-linked list. + public class ListNode + { + public int val; + public ListNode next; + public ListNode(int val = 0, ListNode next = null) + { + this.val = val; + this.next = next; + } + } + public bool IsPalindrome(ListNode head) + { + if (head.next == null) return true; + + ListNode begin = head; + ListNode slow = head; + ListNode fast = head; + + while (slow != null && fast != null && fast.next != null) + { + slow = slow.next; + fast = fast.next.next; + } + + slow = _reverseList(slow); + + while (slow != null) + { + if (begin.val != slow.val) + return false; + + begin = begin.next; + slow = slow.next; + + } + + return true; + } + + private ListNode _reverseList(ListNode head) + { + if (head == null || head.next == null) return head; + + ListNode prev = new(-1); + ListNode cur = head; + + while (cur != null) + { + ListNode next = cur.next; + ListNode nextPrev = prev.next; + + prev.next = cur; + cur.next = nextPrev; + + cur = next; + + } + return prev.next; + } + } +} \ No newline at end of file From 7735b0ebf10e7fa21a2a3c7f3549e1093dfe785e Mon Sep 17 00:00:00 2001 From: tai Date: Sat, 10 Aug 2024 14:28:33 +0700 Subject: [PATCH 13/39] tuantai0708 - Day1008 --- Topic2_LinkedList/Day1008/Exercise1.cs | 51 ++++++++++++++++++++ Topic2_LinkedList/Day1008/Exercise2.cs | 66 ++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 Topic2_LinkedList/Day1008/Exercise1.cs create mode 100644 Topic2_LinkedList/Day1008/Exercise2.cs diff --git a/Topic2_LinkedList/Day1008/Exercise1.cs b/Topic2_LinkedList/Day1008/Exercise1.cs new file mode 100644 index 0000000..567b12a --- /dev/null +++ b/Topic2_LinkedList/Day1008/Exercise1.cs @@ -0,0 +1,51 @@ +//https://leetcode.com/problems/remove-duplicates-from-sorted-list/ + +/* ++ I am going to have 2 pointers, previous and current + + If previous value equals current value => delete current by connecting previous pointer with next pointer + + Otherwise, move prev pointer into next position ++ Move cur pointer into next position + +Space complexity: O(1) +Time complexity: O(n) +*/ + +namespace Day1008 +{ + public class Exercise1 + { + // Definition for singly-linked list. + public class ListNode + { + public int val; + public ListNode next; + public ListNode(int val = 0, ListNode next = null) + { + this.val = val; + this.next = next; + } + } + public ListNode DeleteDuplicates(ListNode head) + { + if (head == null || head.next == null) return head; + + ListNode result = head; + + ListNode prev = head; + ListNode cur = head.next; + + while (cur != null) + { + ListNode next = cur.next; + + if (prev.val == cur.val) + prev.next = next; + else + prev = cur; + + cur = next; + } + return result; + } + } +} \ No newline at end of file diff --git a/Topic2_LinkedList/Day1008/Exercise2.cs b/Topic2_LinkedList/Day1008/Exercise2.cs new file mode 100644 index 0000000..f28a7ff --- /dev/null +++ b/Topic2_LinkedList/Day1008/Exercise2.cs @@ -0,0 +1,66 @@ +//https://leetcode.com/problems/merge-k-sorted-lists/ + +/* ++ Using priorityQueue + + Push all the first element in every single list of lists + ++ Iterating until that queue is empty + + For every loop, get the first element + => push it into result list + => push the next element of the first element in list into queue + +Space complexity: O(n) +Time complexity: O((k * n * logk) + (k * logk)) +*/ +namespace Day1008 +{ + public class Exercise2 + { + // Definition for singly-linked list. + public class ListNode + { + public int val; + public ListNode next; + public ListNode(int val = 0, ListNode next = null) + { + this.val = val; + this.next = next; + } + } + public ListNode MergeKLists(ListNode[] lists) + { + //k: the length of lists + //n: the length of every list in lists + int length = lists.Length; + + if (length == 0) return null; + + ListNode dummyNode = new(-1); + ListNode result = dummyNode; + + PriorityQueue priorityQueue = new(); + + foreach (ListNode list in lists) + { + if (list != null) + priorityQueue.Enqueue(list, list.val); // k * logk + } + + + while (priorityQueue.Count > 0) // k * n + { + ListNode item = priorityQueue.Dequeue();// logk + + dummyNode.next = item; + dummyNode = dummyNode.next; + + if (item.next != null) + priorityQueue.Enqueue(item.next, item.next.val);// logk + + } + // => k * n * logk + + return result.next; + } + } +} \ No newline at end of file From 5c1659a5163307e60f89ac1e1a2573e2f2c86ca5 Mon Sep 17 00:00:00 2001 From: tai Date: Tue, 13 Aug 2024 12:01:05 +0700 Subject: [PATCH 14/39] tuantai0708 - Day1308 --- Topic3_StackQueue/Day1308/Exercise1.cs | 46 ++++++++++++++++++++++++ Topic3_StackQueue/Day1308/Exercise2.cs | 49 ++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 Topic3_StackQueue/Day1308/Exercise1.cs create mode 100644 Topic3_StackQueue/Day1308/Exercise2.cs diff --git a/Topic3_StackQueue/Day1308/Exercise1.cs b/Topic3_StackQueue/Day1308/Exercise1.cs new file mode 100644 index 0000000..40599be --- /dev/null +++ b/Topic3_StackQueue/Day1308/Exercise1.cs @@ -0,0 +1,46 @@ +//https://leetcode.com/problems/valid-parentheses/ + +/* ++ Using stack ++ Always push open parenthesis ++ If current char is closed parenthesis => compare that to the top element in stack(open parenthesis) + =>if it is different => false; + ++ Check whether stack is empty or not + +Space complexity: O(n) +Time complexity: O(n) +*/ + +namespace Day1308 +{ + public class Exercise1 + { + public bool IsValid(string str) + { + Stack stack = new(); + + foreach (char s in str) + { + if (s == '(' || s == '[' || s == '{') + { + stack.Push(s); + } + else + { + if (stack.Count == 0) return false; + + char top = stack.Pop(); + if ((top == '(' && s != ')') || + (top == '[' && s != ']') || + (top == '{' && s != '}')) + { + return false; + } + } + } + + return stack.Count == 0; + } + } +} \ No newline at end of file diff --git a/Topic3_StackQueue/Day1308/Exercise2.cs b/Topic3_StackQueue/Day1308/Exercise2.cs new file mode 100644 index 0000000..1bc6173 --- /dev/null +++ b/Topic3_StackQueue/Day1308/Exercise2.cs @@ -0,0 +1,49 @@ +//https://leetcode.com/problems/min-stack/ + +/* ++ Using stack ++ I will have 2 stacks which have the same size + + First: push all elements + + Second: push minimum element at the top + +Space complexity: O(n^2) +Time complexity: O(1) +*/ +namespace Day1308 +{ + public class Exercise2 + { + public class MinStack + { + private Stack stack; + private Stack minStack; + public MinStack() + { + stack = new(); + minStack = new(); + } + + public void Push(int val) + { + stack.Push(val); + minStack.Push(Math.Min(val, minStack.Count == 0 ? val : minStack.Peek())); + } + + public void Pop() + { + stack.Pop(); + minStack.Pop(); + } + + public int Top() + { + return stack.Peek(); + } + + public int GetMin() + { + return minStack.Peek(); + } + } + } +} \ No newline at end of file From 7435b95ce6158875edbfa492a66dd8c7440d398d Mon Sep 17 00:00:00 2001 From: tai Date: Wed, 14 Aug 2024 18:49:19 +0700 Subject: [PATCH 15/39] tuantai0708 - Day1408 --- Topic3_StackQueue/Day1408/Exercise1.cs | 48 +++++++++++++++++++++++ Topic3_StackQueue/Day1408/Exercise2.cs | 53 ++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 Topic3_StackQueue/Day1408/Exercise1.cs create mode 100644 Topic3_StackQueue/Day1408/Exercise2.cs diff --git a/Topic3_StackQueue/Day1408/Exercise1.cs b/Topic3_StackQueue/Day1408/Exercise1.cs new file mode 100644 index 0000000..079d06a --- /dev/null +++ b/Topic3_StackQueue/Day1408/Exercise1.cs @@ -0,0 +1,48 @@ +//https://leetcode.com/problems/implement-stack-using-queues/ + +/* ++ After adding a new element, we will revert queue as stack + +Space complexity: O(n) +Time complexity: O(n) +*/ + +namespace Day1408 +{ + public class Exercise1 + { + public class MyStack + { + private Queue queue; + + public MyStack() + { + queue = new(); + } + + public void Push(int x) + { + queue.Enqueue(x); + + //convert queue into stack + for (int i = 0; i < queue.Count - 1; i++) + queue.Enqueue(queue.Dequeue()); + } + + public int Pop() + { + return queue.Dequeue(); + } + + public int Top() + { + return queue.Peek(); + } + + public bool Empty() + { + return queue.Count == 0; + } + } + } +} \ No newline at end of file diff --git a/Topic3_StackQueue/Day1408/Exercise2.cs b/Topic3_StackQueue/Day1408/Exercise2.cs new file mode 100644 index 0000000..639092b --- /dev/null +++ b/Topic3_StackQueue/Day1408/Exercise2.cs @@ -0,0 +1,53 @@ +//https://leetcode.com/problems/evaluate-reverse-polish-notation/ + + +/* ++ Using stack + + If element is number => push to stack + + If not + + Get 2 elements from the top => count result => add result into stack for the next calculation + +Space complexity: O(n) +Time complexity: O(n) +*/ +namespace Day1408 +{ + public class Exercise2 + { + public int EvalRPN(string[] tokens) + { + if (tokens.Length == 1) return int.Parse(tokens[0]); + + int result = 0; + Stack stack = new(); + + foreach (string token in tokens) + { + if (int.TryParse(token, out int number)) + { + stack.Push(number); + } + else + { + int number2 = stack.Pop(); + int number1 = stack.Pop(); + + if (token == "+") + result = number1 + number2; + else if (token == "-") + result = number1 - number2; + else if (token == "*") + result = number1 * number2; + else + result = number1 / number2; + + stack.Push(result); + + } + } + + + return result; + } + } +} \ No newline at end of file From 61ba7e413c11e3362c0ecf539e42d21b57ccc628 Mon Sep 17 00:00:00 2001 From: tai Date: Thu, 15 Aug 2024 20:20:53 +0700 Subject: [PATCH 16/39] tuantai0708 - Day1508 --- Topic3_StackQueue/Day1508/Exercise1.cs | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 Topic3_StackQueue/Day1508/Exercise1.cs diff --git a/Topic3_StackQueue/Day1508/Exercise1.cs b/Topic3_StackQueue/Day1508/Exercise1.cs new file mode 100644 index 0000000..0209459 --- /dev/null +++ b/Topic3_StackQueue/Day1508/Exercise1.cs @@ -0,0 +1,40 @@ +//https://leetcode.com/problems/daily-temperatures/ + +/* ++ Using monotomic decreasing + + to ensure that stack is monotomic decreasing => the top element is smallest and the last element is biggest + + If not => pop until find right position for the current element + +Space complexity: O(n) +Time complexity: O(n^2) +*/ + +namespace Day1508 +{ + public class Exercise1 + { + public int[] DailyTemperatures(int[] temperatures) + { + int length = temperatures.Length; + + Stack stack = new(); + + int[] result = new int[length]; + + for (int curDay = 0; curDay < length; ++curDay) + { + //to ensure that stack is monotomic decreasing + //(the top element is smallest and the last element is biggest) + while (stack.Count != 0 && temperatures[curDay] > temperatures[stack.Peek()]) + { + int prevDay = stack.Pop(); + + result[prevDay] = curDay - prevDay; + } + stack.Push(curDay); + } + + return result; + } + } +} \ No newline at end of file From d1629a2b5fbbadf618e713d71c14b25f7af937ab Mon Sep 17 00:00:00 2001 From: tai Date: Fri, 16 Aug 2024 10:11:17 +0700 Subject: [PATCH 17/39] tuantait0708 - Day1608 --- Topic3_StackQueue/Day1608/Exercise1.cs | 43 ++++++++++++++++++ Topic3_StackQueue/Day1608/Exercise2.cs | 62 ++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 Topic3_StackQueue/Day1608/Exercise1.cs create mode 100644 Topic3_StackQueue/Day1608/Exercise2.cs diff --git a/Topic3_StackQueue/Day1608/Exercise1.cs b/Topic3_StackQueue/Day1608/Exercise1.cs new file mode 100644 index 0000000..fca8f21 --- /dev/null +++ b/Topic3_StackQueue/Day1608/Exercise1.cs @@ -0,0 +1,43 @@ +//https://leetcode.com/problems/reveal-cards-in-increasing-order/ + +/* ++ Sort array first ++ Add position of all elements into queue + ++ When looping every element in array + + Assign the current element into (the position of the front element in queue) + + Move the next position to the end + +Space complexity: O(n) +Time complexity: O(n) +*/ +namespace Day1608 +{ + public class Exercise1 + { + public int[] DeckRevealedIncreasing(int[] deck) + { + Array.Sort(deck); + + Queue queue = new(); + + int length = deck.Length; + + int[] result = new int[length]; + + for (int i = 0; i < length; ++i) + queue.Enqueue(i); + + foreach (int num in deck) + { + int position = queue.Dequeue(); + result[position] = num; + + if (queue.Count != 0) + queue.Enqueue(queue.Dequeue()); + } + + return result; + } + } +} \ No newline at end of file diff --git a/Topic3_StackQueue/Day1608/Exercise2.cs b/Topic3_StackQueue/Day1608/Exercise2.cs new file mode 100644 index 0000000..989101d --- /dev/null +++ b/Topic3_StackQueue/Day1608/Exercise2.cs @@ -0,0 +1,62 @@ +//https://leetcode.com/problems/implement-queue-using-stacks/ + +/* ++ Push as usual ++ Before peeking or popping => revert stack + +Space complexity: O(n) +Time complexity: O(n) +*/ + +namespace Day1608 +{ + public class Exercise2 + { + public class MyQueue + { + private Stack stack; + private Stack temp; + public MyQueue() + { + stack = new(); + temp = new(); + } + + public void Push(int x) + { + stack.Push(x); + } + + public int Pop() + { + while (stack.Count > 0) + temp.Push(stack.Pop()); + + int top = temp.Pop(); + + while (temp.Count > 0) + stack.Push(temp.Pop()); + + return top; + } + + public int Peek() + { + while (stack.Count > 0) + temp.Push(stack.Pop()); + + int peek = temp.Peek(); + + while (temp.Count > 0) + stack.Push(temp.Pop()); + + return peek; + } + + public bool Empty() + { + return stack.Count == 0; + } + } + } +} \ No newline at end of file From 2b64003c0b5d8a4d8740071ae57d72cfac44dabd Mon Sep 17 00:00:00 2001 From: tai Date: Sat, 17 Aug 2024 11:25:45 +0700 Subject: [PATCH 18/39] tuantai0708 - Day1708 --- Topic3_StackQueue/Day1708/Exercise1.cs | 103 +++++++++++++++++++++++++ Topic3_StackQueue/Day1708/Exercise2.cs | 37 +++++++++ 2 files changed, 140 insertions(+) create mode 100644 Topic3_StackQueue/Day1708/Exercise1.cs create mode 100644 Topic3_StackQueue/Day1708/Exercise2.cs diff --git a/Topic3_StackQueue/Day1708/Exercise1.cs b/Topic3_StackQueue/Day1708/Exercise1.cs new file mode 100644 index 0000000..27ab748 --- /dev/null +++ b/Topic3_StackQueue/Day1708/Exercise1.cs @@ -0,0 +1,103 @@ +//https://leetcode.com/problems/design-circular-queue/ + +/* ++ Using linked list technique + + I will have 2 pointers at the beginning and at the end + + With enqueue => add at the end + + With dequeue => remove at the beginning + +Space complexity: O(k) +Time complexity: O(n) +*/ + +namespace Day1708 +{ + public class Exercise1 + { + public class ListNode + { + public int val; + public ListNode next; + public ListNode(int val = 0, ListNode next = null) + { + this.val = val; + this.next = next; + } + } + public class MyCircularQueue + { + private int _total = 0; + private ListNode _frontPointer; + private ListNode _rearPointer; + + public MyCircularQueue(int k) + { + _total = k; + _frontPointer = null; + _rearPointer = null; + } + + public bool EnQueue(int value) + { + if (IsFull() == true) return false; + + ListNode node = new(value); + + //the first added element + if (_frontPointer == null && _rearPointer == null) + { + _frontPointer = node; + _rearPointer = node; + } + else + { + _rearPointer.next = node; + _rearPointer = node; + } + + --_total; + return true; + + } + + public bool DeQueue() + { + if (IsEmpty() == true) return false; + + _frontPointer = _frontPointer.next; + + //if only element in linked list is deleted => assign null to _front and _rear pointer + if (_frontPointer == null) + _rearPointer = null; + + ++_total; + return true; + + } + + public int Front() + { + if (IsEmpty()) return -1; + + return _frontPointer.val; + } + + public int Rear() + { + if (IsEmpty()) return -1; + + return _rearPointer.val; + } + + public bool IsEmpty() + { + return _frontPointer == null && _rearPointer == null; + } + + public bool IsFull() + { + return _total == 0; + } + } + } +} \ No newline at end of file diff --git a/Topic3_StackQueue/Day1708/Exercise2.cs b/Topic3_StackQueue/Day1708/Exercise2.cs new file mode 100644 index 0000000..c774b6e --- /dev/null +++ b/Topic3_StackQueue/Day1708/Exercise2.cs @@ -0,0 +1,37 @@ +//https://leetcode.com/problems/find-the-winner-of-the-circular-game/ + +/* ++ Add idx element into array ++ Looping queue until there is only one element + + To ignore k - 1 element and push it into queue + + to dequeue k element + +Space complexity: O(n) +Time complexity: O(n * k) +*/ + +namespace Day1708 +{ + public class Exercise2 + { + public int FindTheWinner(int n, int k) + { + Queue queue = new(); + --k; + + for (int i = 1; i <= n; ++i) + queue.Enqueue(i); + + while (queue.Count > 1) + { + for (int i = 0; i < k; ++i) + queue.Enqueue(queue.Dequeue()); + + queue.Dequeue(); + + } + + return queue.Peek(); + } + } +} \ No newline at end of file From 36d7f61d26add11ade77e7ac284ce20aca1961ea Mon Sep 17 00:00:00 2001 From: tai Date: Mon, 19 Aug 2024 10:48:21 +0700 Subject: [PATCH 19/39] tuantai0708 - Day1808 --- Topic3_StackQueue/Day1808/Exercise1.cs | 38 ++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Topic3_StackQueue/Day1808/Exercise1.cs diff --git a/Topic3_StackQueue/Day1808/Exercise1.cs b/Topic3_StackQueue/Day1808/Exercise1.cs new file mode 100644 index 0000000..be70479 --- /dev/null +++ b/Topic3_StackQueue/Day1808/Exercise1.cs @@ -0,0 +1,38 @@ +//https://leetcode.com/problems/number-of-recent-calls/ + +/* ++ When receiving t I must ensure that + + queue is in range [t - 3000, t] + + Otherwise, dequeue the front element + +Space complexity: O(n) +Time complexity: O(n) +*/ + +namespace Day1808 +{ + public class Exercise1 + { + public class RecentCounter + { + private Queue queue; + public RecentCounter() + { + queue = new(); + } + + public int Ping(int t) + { + int mini = t - 3000; + int maxi = t; + + queue.Enqueue(t); + + while (queue.Count != 0 && (mini > queue.Peek() || queue.Peek() > maxi)) + queue.Dequeue(); + + return queue.Count; + } + } + } +} \ No newline at end of file From 332f05de1fef117a2c44d2e273c17c39fcfff1db Mon Sep 17 00:00:00 2001 From: tai Date: Mon, 19 Aug 2024 11:10:59 +0700 Subject: [PATCH 20/39] tuantai0708 - Day1908 --- Topic4_Recursion/Day1908/Exercise1.cs | 24 ++++++++++++ Topic4_Recursion/Day1908/Exercise2.cs | 53 +++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 Topic4_Recursion/Day1908/Exercise1.cs create mode 100644 Topic4_Recursion/Day1908/Exercise2.cs diff --git a/Topic4_Recursion/Day1908/Exercise1.cs b/Topic4_Recursion/Day1908/Exercise1.cs new file mode 100644 index 0000000..3d3eb31 --- /dev/null +++ b/Topic4_Recursion/Day1908/Exercise1.cs @@ -0,0 +1,24 @@ +//https://leetcode.com/problems/fibonacci-number/description/ + +/* ++ base case: n = 0 or n = 1 + +Space complexity: O(1) +Time complexity: O(n) +*/ +namespace Day1908 +{ + public class Exercise1 + { + public int Fib(int n) + { + if (n == 0) + return 0; + + if (n == 1) + return 1; + + return Fib(n - 1) + Fib(n - 2); + } + } +} \ No newline at end of file diff --git a/Topic4_Recursion/Day1908/Exercise2.cs b/Topic4_Recursion/Day1908/Exercise2.cs new file mode 100644 index 0000000..6727152 --- /dev/null +++ b/Topic4_Recursion/Day1908/Exercise2.cs @@ -0,0 +1,53 @@ +//https://leetcode.com/problems/pascals-triangle + +/* ++ To have base array which only has one element ++ To build next 1d array based on temp array + +Space complexity: O(n^2) +Time complexity: O(n^2) +*/ + +namespace Day1908 +{ + public class Exercise2 + { + public IList> Generate(int numRows) + { + List> result = []; + List temp = new() { 1 }; + + result.Add(temp); + + for (int i = 2; i <= numRows; ++i) + { + List array = _buildArray(temp, i); + + result.Add(array); + + temp = array; + + } + + + return result; + } + + private List _buildArray(List arr, int n) + { + List result = new(new int[n]); + + for (int i = 0; i < n; ++i) + { + if (i == 0) + result[i] = arr[i]; + else if (i == n - 1) + result[i] = arr[i - 1]; + else + result[i] = arr[i - 1] + arr[i]; + + } + return result; + } + } +} \ No newline at end of file From 83f39806c1f99faf7655c9b64608f22a35b1aac7 Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Wed, 21 Aug 2024 14:11:19 +0700 Subject: [PATCH 21/39] tuantai0708 - Day2008 --- Topic4_Recursion/Day2108/Exercise1.cs | 121 ++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 Topic4_Recursion/Day2108/Exercise1.cs diff --git a/Topic4_Recursion/Day2108/Exercise1.cs b/Topic4_Recursion/Day2108/Exercise1.cs new file mode 100644 index 0000000..e58f7f6 --- /dev/null +++ b/Topic4_Recursion/Day2108/Exercise1.cs @@ -0,0 +1,121 @@ +//https://leetcode.com/problems/decode-string/ + +namespace Day2108 +{ + public class Exercise1 + { + + //Recursion + + /* + + To loop until find any digit => start of suitable string + + Step 1: To ignore '[' + + Step 2: To build string + + Step 3: To ignore ']' + + Step 4: To loop number times to build string based on step 2 + + Otherwise + + add to current string + + Space complexity: O(maxK * n) => maxK is the maximum repeat + Time complexity: O(maxK * n) => maxK is the maximum repeat + */ + public class Solution1 + { + public string DecodeString(string str) + { + int index = 0; + return _backTracking(str, ref index); + } + + private string _backTracking(string str, ref int index) + { + string result = ""; + + while (index < str.Length && str[index] != ']') + { + if (char.IsDigit(str[index])) + { + // Xử lý số để tìm ra số lần lặp + int number = 0; + while (index < str.Length && char.IsDigit(str[index])) + { + number = number * 10 + (str[index] - '0'); + index++; + } + + // To ignore '[' + index++; + + // Start recursion + string decodedString = _backTracking(str, ref index); + + // To ignore ']' + index++; + + // to build string based on number + for (int i = 0; i < number; i++) + result += decodedString; + } + else + { + // if it's type char => add to result + result += str[index]; + index++; + } + } + + return result; + } + } + + //Stack + public class Solution2 + { + public string DecodeString(string str) + { + Stack stack = new(); + foreach (char s in str) + { + if (s != ']') + stack.Push(s.ToString()); + else + { + string tempString = ""; + //pop until find suitable string + while (stack.Count != 0 && stack.Peek().All(c => char.IsLower(c))) + tempString += stack.Pop(); + + tempString = new string(tempString.Reverse().ToArray()); + + //remove open square bracket + stack.Pop(); + + string tempNumber = ""; + //pop until find suitable number + while (stack.Count != 0 && int.TryParse(stack.Peek(), out int check)) + tempNumber += stack.Pop(); + + int number = int.Parse(tempNumber.Reverse().ToArray()); + + stack.Push(new string(_buildReverseString(tempString, number))); + + } + } + + string result = ""; + while (stack.Count != 0) + result += stack.Pop(); + + return new string(result.Reverse().ToArray()); + } + private char[] _buildReverseString(string s, int number) + { + string result = ""; + + for (int i = 1; i <= number; ++i) + result += s; + return result.Reverse().ToArray(); + } + } + } +} \ No newline at end of file From d52529bb272615e0940881bab64b27b69f9f4380 Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Wed, 21 Aug 2024 14:28:54 +0700 Subject: [PATCH 22/39] tuantai0708 - Day2108 --- Topic4_Recursion/Day2008/Exercise1.cs | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Topic4_Recursion/Day2008/Exercise1.cs diff --git a/Topic4_Recursion/Day2008/Exercise1.cs b/Topic4_Recursion/Day2008/Exercise1.cs new file mode 100644 index 0000000..42b18cb --- /dev/null +++ b/Topic4_Recursion/Day2008/Exercise1.cs @@ -0,0 +1,36 @@ +//https://leetcode.com/problems/powx-n/description/ + +/* ++ Base case: n = 1 + + To get current x * recursive function after minusing n 1 value + + If n is even number => multiple x together to reduce time complexity + +Space complexity: O(N) +Time complexity: O(N) +*/ +namespace Day2008 +{ + public class Exercise1 + { + public double MyPow(double x, int n) + { + if (n == 0) + return 1; + + long nn = n; + + double ans = _backTracking(x, Math.Abs(nn)); + + return n > 0 ? ans : (double)1 / ans; + } + + private double _backTracking(double x, double n) + { + if (n == 1) return x; + + if (n % 2 == 0) return _backTracking(x * x, n / 2); + + return x * _backTracking(x, n - 1); + } + } +} \ No newline at end of file From 213e06bf8e97ea75bd67c730d231d2295f5b8f3e Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Thu, 22 Aug 2024 12:13:03 +0700 Subject: [PATCH 23/39] tuantai0708 - Day2208 --- Topic4_Recursion/Day2208/Exercise1.cs | 51 ++++++++++++++++++++ Topic4_Recursion/Day2208/Exercise2.cs | 68 +++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 Topic4_Recursion/Day2208/Exercise1.cs create mode 100644 Topic4_Recursion/Day2208/Exercise2.cs diff --git a/Topic4_Recursion/Day2208/Exercise1.cs b/Topic4_Recursion/Day2208/Exercise1.cs new file mode 100644 index 0000000..947492c --- /dev/null +++ b/Topic4_Recursion/Day2208/Exercise1.cs @@ -0,0 +1,51 @@ +//https://leetcode.com/problems/find-the-winner-of-the-circular-game/ + + +namespace Day2208 +{ + public class Exercise1 + { + public class Solution1 + { + /* + + After removing element at k, the new idx will begin at: idx + 1 (idx + k) + + Space complexity: O(N) + Time complexity: O(N) + */ + public int FindTheWinner(int n, int k) + { + return _func(n, k) + 1; + } + + private int _func(int n, int k) + { + if (n == 1) + return 0; + + return (_func(n - 1, k) + k) % n; + } + } + + + public class Solution2 + { + /* + + After removing element at k, the new idx will begin at: idx + 1 (idx + k) + + Space complexity: O(N) + Time complexity: O(1) + */ + public int FindTheWinner(int n, int k) + { + int winner = 0; + + for (int i = 2; i <= n; ++i) + winner = (winner + k) % i; + + //to make 0 indexing become 1 indexing + return winner + 1; + } + } + } +} \ No newline at end of file diff --git a/Topic4_Recursion/Day2208/Exercise2.cs b/Topic4_Recursion/Day2208/Exercise2.cs new file mode 100644 index 0000000..8249716 --- /dev/null +++ b/Topic4_Recursion/Day2208/Exercise2.cs @@ -0,0 +1,68 @@ +//https://leetcode.com/problems/reorder-list/ + +/* ++ Move to get the last element in linked list ++ Add that last element between current zipper and zipperNext ++ Continue to loop the next element (ignoring the element which is added recently) + +Space complexity: O(N) +Time complexity: O(N) +*/ + +namespace Day2208 +{ + public class ListNode + { + public int val; + public ListNode next; + public ListNode(int val = 0, ListNode next = null) + { + this.val = val; + this.next = next; + } + } + public class Exercise2 + { + ListNode start; + + public void ReorderList(ListNode head) + { + if (head == null || head.next == null || head.next.next == null) return; + start = head; + scanNext(head); // Recursion builds the output list. + } + + + private void scanNext(ListNode node) + { + if (node == null) return; // If end of input list, start returning from recursion. + + scanNext(node.next); // If more input list, keep recursing. + + if (start.next == null) return; // Unwinding from recursion. If output list done, then do nothing + ListNode startNext = start.next; // Save next node from first half of list. + + // If first-half and second-half met in middle, then done merging. + if (start == node) + start.next = null; + else + { + //used for list has even length + if (node == startNext) + { + start = node; + start.next = null; + + //used for list has odd length + } + else + { + node.next = startNext; // Finish inserting node from recursion/second-half + start.next = node; + + start = startNext; + } + } + } + } +} \ No newline at end of file From 56a747695fdff66986dd5601475cf071f880f7d8 Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Fri, 23 Aug 2024 18:23:02 +0700 Subject: [PATCH 24/39] tuantai0708 - Day2308 --- Topic4_Recursion/Day2308/Exercise1.cs | 64 +++++++++++++++++++++++++++ Topic4_Recursion/Day2308/Exercise2.cs | 48 ++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 Topic4_Recursion/Day2308/Exercise1.cs create mode 100644 Topic4_Recursion/Day2308/Exercise2.cs diff --git a/Topic4_Recursion/Day2308/Exercise1.cs b/Topic4_Recursion/Day2308/Exercise1.cs new file mode 100644 index 0000000..9915275 --- /dev/null +++ b/Topic4_Recursion/Day2308/Exercise1.cs @@ -0,0 +1,64 @@ +//https://leetcode.com/problems/letter-combinations-of-a-phone-number/ + +/* ++ We will get value in strs[] based on value of current position ++ After that, we will add that to "temp" string ++ Run recursive function in the next idx ++ Remove the last element in temp string + +Space complexity: O(N * 4^N): (4 is longest length in strs) +Time complexity: O(N * 4^N) (4 is longest length in strs) +*/ + +namespace Day2308 +{ + public class Exercise1 + { + private string[] strs = { + "-1", + "-1", + "abc", + "def", + "ghi", + "jkl", + "mno", + "pqrs", + "tuv", + "wxyz", + }; + public IList LetterCombinations(string digits) + { + IList result = new List(); + + if (digits.Length == 0) + return result; + + string temp = ""; + _backTracking(0, digits, result, temp); + + return result; + } + + private void _backTracking(int idx, string digits, IList result, string temp) + { + if (temp.Length == digits.Length) + { + result.Add(temp); + return; + } + + for (int i = idx; i < digits.Length; ++i) + { + int digit = int.Parse(digits[i].ToString()); + for (int j = 0; j < strs[digit].Length; ++j) + { + temp += strs[digit][j]; + + _backTracking(i + 1, digits, result, temp); + + temp = temp.Substring(0, temp.Length - 1); + } + } + } + } +} \ No newline at end of file diff --git a/Topic4_Recursion/Day2308/Exercise2.cs b/Topic4_Recursion/Day2308/Exercise2.cs new file mode 100644 index 0000000..8ee1069 --- /dev/null +++ b/Topic4_Recursion/Day2308/Exercise2.cs @@ -0,0 +1,48 @@ +//https://leetcode.com/problems/generate-parentheses/ + +/* ++ At every position, I will have 2 options but the number of +open parenthesis must be lower or equals than close parenthesis + + Add "(" into string + + Add ")" into string + +Space complexity: O(N) (recursion stack) +Time complexity: O(2^(2 * N)): Every position can have 2 possible parenthesis (open or close) +*/ + +namespace Day2308 +{ + public class Exercise2 + { + public IList GenerateParenthesis(int n) + { + IList result = []; + string temp = ""; + + _backTracking(n, n, temp, result); + + return result; + } + + private void _backTracking(int open, int close, string temp, IList result) + { + if (open == 0 && close == 0) + { + result.Add(temp); + return; + } + + if (open >= 0 && open <= close) + { + temp += "("; + _backTracking(open - 1, close, temp, result); + + temp = temp.Substring(0, temp.Length - 1); + + temp += ")"; + _backTracking(open, close - 1, temp, result); + + } + } + } +} \ No newline at end of file From 2faca055e8dc972f68148845758232b373014cac Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Wed, 28 Aug 2024 09:31:16 +0700 Subject: [PATCH 25/39] tuantai0708 - Day2708 --- Topic4_Recursion/Day2708/Exercise1.cs | 68 +++++++++++++++++++++++++++ Topic4_Recursion/Day2708/Exercise2.cs | 61 ++++++++++++++++++++++++ Topic4_Recursion/Day2708/Exercise3.cs | 60 +++++++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 Topic4_Recursion/Day2708/Exercise1.cs create mode 100644 Topic4_Recursion/Day2708/Exercise2.cs create mode 100644 Topic4_Recursion/Day2708/Exercise3.cs diff --git a/Topic4_Recursion/Day2708/Exercise1.cs b/Topic4_Recursion/Day2708/Exercise1.cs new file mode 100644 index 0000000..4dd1f98 --- /dev/null +++ b/Topic4_Recursion/Day2708/Exercise1.cs @@ -0,0 +1,68 @@ +//https://leetcode.com/problems/path-with-maximum-gold/description/ + +/* ++ At every position which has gold value + => We will run dfs on that position from top, left, down to right + => Find maximum between these 4 values + +Space complexity: O(4 ^ (M * N)): (4 is four paths which each position can go) +Time complexity: O(M * N * 4 ^ (M * N)) (4 is four paths which each position can go) +*/ + +namespace Day2708 +{ + public class Exercise1 + { + public int GetMaximumGold(int[][] grid) + { + int result = 0; + + int m = grid.Length; + int n = grid[0].Length; + + for (int i = 0; i < m; ++i) + { + for (int j = 0; j < n; ++j) + { + if (grid[i][j] != 0) + { + int calc = _dfs(grid, m, n, i, j); + + result = Math.Max(result, calc); + } + + } + } + + return result; + } + + private int _dfs(int[][] grid, int m, int n, int i, int j) + { + if (i < 0 || j < 0 || i == m || j == n || grid[i][j] == 0) + return 0; + + int maxGold = 0; + + int curVal = grid[i][j]; + + grid[i][j] = 0; // to mark this cell as visited + + maxGold = + FindMax(maxGold, + curVal + _dfs(grid, m, n, i - 1, j), + curVal + _dfs(grid, m, n, i, j - 1), + curVal + _dfs(grid, m, n, i + 1, j), + curVal + _dfs(grid, m, n, i, j + 1)); + + grid[i][j] = curVal; // to return back value of this cell + + return maxGold; + } + + static int FindMax(params int[] numbers) + { + return numbers.Max(); + } + } +} \ No newline at end of file diff --git a/Topic4_Recursion/Day2708/Exercise2.cs b/Topic4_Recursion/Day2708/Exercise2.cs new file mode 100644 index 0000000..577ef41 --- /dev/null +++ b/Topic4_Recursion/Day2708/Exercise2.cs @@ -0,0 +1,61 @@ +//https://leetcode.com/problems/word-search/ + +/* ++ At every position which starts with the first character as word string + => We will run dfs on that position from top, left, down to right + => To check whether from that position we can find word in board or not + +Space complexity: O(4 ^ (M * N)): (4 is four paths which each position can go) +Time complexity: O(M * N * 4 ^ (M * N)) (4 is four paths which each position can go) +*/ + +namespace Day2708 +{ + public class Exercise2 + { + public bool 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 (board[i][j].Equals(word[0])) + { + bool check = _dfs(board, m, n, i, j, 0, word); + + if (check == true) + return true; + } + + } + } + + return false; + } + + private bool _dfs(char[][] board, int m, int n, int i, int j, int idx, string word) + { + if (idx == word.Length) + return true; + + if (i < 0 || j < 0 || i == m || j == n || board[i][j] == '0' || word[idx] != board[i][j]) + return false; + + char curVal = board[i][j]; + + board[i][j] = '0'; // to mark this cell as visited + + bool top = _dfs(board, m, n, i - 1, j, idx + 1, word); + bool left = _dfs(board, m, n, i, j - 1, idx + 1, word); + bool down = _dfs(board, m, n, i + 1, j, idx + 1, word); + bool right = _dfs(board, m, n, i, j + 1, idx + 1, word); + + board[i][j] = curVal; // to return back value of this cell + + return top || left || down || right; + } + } +} \ No newline at end of file diff --git a/Topic4_Recursion/Day2708/Exercise3.cs b/Topic4_Recursion/Day2708/Exercise3.cs new file mode 100644 index 0000000..1ffdfc5 --- /dev/null +++ b/Topic4_Recursion/Day2708/Exercise3.cs @@ -0,0 +1,60 @@ +//https://leetcode.com/problems/palindrome-partitioning/ + +/* ++ To run every element in string + + To check whether string temp after being cut from previous idx to current i is palindrome or not + + If palindrome, run on next idx + + Otherwise => do nothing + +Space complexity: O(N * N) +Time complexity: O(N * 2 ^ N) (2 options whether we decide to choose that element or not) +*/ +namespace Day2708 +{ + public class Exercise3 + { + public IList> Partition(string s) + { + List> result = []; + List temp = new(); + int Length = s.Length; + + _func(s, 0, temp, result); + + return result; + } + + private void _func(string s, int idx, List path, List> result) + { + if (idx == s.Length) + { + result.Add(path.ToArray()); + return; + } + for (int i = idx; i < s.Length; ++i) + { + string temp = s.Substring(idx, i - idx + 1); + //run recursion on string which is palindrome + if (_isPalindrome(temp)) + { + path.Add(temp); + _func(s, i + 1, path, result); + path.RemoveAt(path.Count - 1); + } + } + } + + private bool _isPalindrome(string s) + { + int left = 0; + int right = s.Length - 1; + + while (left < right) + { + if (s[left++] != s[right--]) + return false; + } + return true; + } + } +} \ No newline at end of file From c56371c33ada0d590fe1b5cc68a95abf9992c310 Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Wed, 28 Aug 2024 10:51:04 +0700 Subject: [PATCH 26/39] tuantai0708 - Day2808 --- Topic4_Recursion/Day2808/Exercise1.cs | 44 ++++++++++++++++++++ Topic4_Recursion/Day2808/Exercise2.cs | 59 +++++++++++++++++++++++++++ Topic4_Recursion/Day2808/Exercise3.cs | 37 +++++++++++++++++ Topic4_Recursion/Day2808/Exercise4.cs | 33 +++++++++++++++ 4 files changed, 173 insertions(+) create mode 100644 Topic4_Recursion/Day2808/Exercise1.cs create mode 100644 Topic4_Recursion/Day2808/Exercise2.cs create mode 100644 Topic4_Recursion/Day2808/Exercise3.cs create mode 100644 Topic4_Recursion/Day2808/Exercise4.cs diff --git a/Topic4_Recursion/Day2808/Exercise1.cs b/Topic4_Recursion/Day2808/Exercise1.cs new file mode 100644 index 0000000..ce83703 --- /dev/null +++ b/Topic4_Recursion/Day2808/Exercise1.cs @@ -0,0 +1,44 @@ +//https://leetcode.com/problems/combinations + +/* ++ To run every idx based on n + + With every idx => push it to temp array and continue to run recursion + on the next idx + + Push to result array when length of temp array equals to k + + Must remember to remove the last idx in temp array for the next iteration + +Space complexity: O(K) +Time complexity: O(N * K) + => The backtrack function is called n times, because there are n possible starting points for the subset. + For each starting point, the backtrack function iterates through all k elements +*/ +namespace Day2808 +{ + public class Exercise1 + { + public IList> Combine(int n, int k) + { + List> result = []; + List temp = []; + + _backTracking(n, k, 1, temp, result); + + return result; + } + + private void _backTracking(int n, int k, int idx, List temp, List> result) + { + if (temp.Count == k) + { + result.Add(temp.ToArray()); + return; + } + for (int i = idx; i <= n; ++i) + { + temp.Add(i); + _backTracking(n, k, i + 1, temp, result); + temp.RemoveAt(temp.Count - 1); + } + } + } +} \ No newline at end of file diff --git a/Topic4_Recursion/Day2808/Exercise2.cs b/Topic4_Recursion/Day2808/Exercise2.cs new file mode 100644 index 0000000..cfa7446 --- /dev/null +++ b/Topic4_Recursion/Day2808/Exercise2.cs @@ -0,0 +1,59 @@ +//https://leetcode.com/problems/combination-sum-ii/ + +/* ++ To run every element of input array + + With every idx => push it to temp array and continue to run recursion + on the next idx + + Push to result array when target equals to 0 + + Must remember to remove the last idx in temp array for the next iteration + + Remove duplicate combinations by sorting array first and then move the new element in array + +Space complexity: O(K * N) + => k is the number of valid combinations + => n is the length of each combination +Time complexity: O(N logn + (K ∗ (2 ^ N)) + => k is number of valid combinations + => The DFS algorithm has a worst-case time complexity of O(2^n) +*/ + +namespace Day2808 +{ + public class Exercise2 + { + public IList> CombinationSum2(int[] candidates, int target) + { + List> result = []; + List temp = []; + + Array.Sort(candidates); + + _backTracking(candidates, target, 0, temp, result); + + return result; + } + + private void _backTracking(int[] candidates, int target, int idx, List temp, List> result) + { + if (target == 0) + { + result.Add(temp.ToArray()); + return; + } + + if (target < 0 || idx == candidates.Length) + return; + + for (int i = idx; i < candidates.Length; ++i) + { + temp.Add(candidates[i]); + + _backTracking(candidates, target - candidates[i], i + 1, temp, result); + + temp.RemoveAt(temp.Count - 1); + + while ((i + 1) < candidates.Length && candidates[i] == candidates[i + 1]) + ++i; + } + } + } +} \ No newline at end of file diff --git a/Topic4_Recursion/Day2808/Exercise3.cs b/Topic4_Recursion/Day2808/Exercise3.cs new file mode 100644 index 0000000..df22945 --- /dev/null +++ b/Topic4_Recursion/Day2808/Exercise3.cs @@ -0,0 +1,37 @@ +//https://leetcode.com/problems/climbing-stairs + +/* ++ To define base case first + + n = 1 => only 1 way to reach the top + + n = 2 => 2 ways to reach the top ++ To run for loop from value 3 by adding 2 previous steps and update step after that + +Space complexity: O(1) +Time complexity: O(N) +*/ + +namespace Day2808 +{ + public class Exercise3 + { + public int ClimbStairs(int n) + { + if (n == 1) return 1; + if (n == 2) return 2; + + int step1 = 1; + int step2 = 2; + + int total = step1 + step2; + + for (int i = 3; i <= n; ++i) + { + total = step1 + step2; + step1 = step2; + step2 = total; + } + + return total; + } + } +} \ No newline at end of file diff --git a/Topic4_Recursion/Day2808/Exercise4.cs b/Topic4_Recursion/Day2808/Exercise4.cs new file mode 100644 index 0000000..e71e081 --- /dev/null +++ b/Topic4_Recursion/Day2808/Exercise4.cs @@ -0,0 +1,33 @@ +//https://leetcode.com/problems/min-cost-climbing-stairs/ + +/* ++ To define base case first + + n = 1 => minimum cost to reach first step is cost[0] + + n = 2 => minimum cost to reach second step is cost[1] ++ To run for loop from value 2 by adding cost[i] with the minimum cost of 2 previous idexes + +Space complexity: O(1) +Time complexity: O(N) +*/ + +namespace Day2808 +{ + public class Exercise4 + { + public int MinCostClimbingStairs(int[] cost) + { + int Length = cost.Length; + + int firstStep = cost[0]; + int secondStep = cost[1]; + for (int i = 2; i < Length; ++i) + { + int miniStep = cost[i] + Math.Min(firstStep, secondStep); + firstStep = secondStep; + secondStep = miniStep; + } + + return Math.Min(firstStep, secondStep); + } + } +} \ No newline at end of file From 62ad9e51915852e5ed72a7ab321afa7061898720 Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Thu, 29 Aug 2024 07:16:50 +0700 Subject: [PATCH 27/39] tuantai0708 - Day2908 --- Topic5_BinarySearch/Day2908/Exercise1.cs | 40 ++++++++++++ Topic5_BinarySearch/Day2908/Exercise2.cs | 78 ++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 Topic5_BinarySearch/Day2908/Exercise1.cs create mode 100644 Topic5_BinarySearch/Day2908/Exercise2.cs diff --git a/Topic5_BinarySearch/Day2908/Exercise1.cs b/Topic5_BinarySearch/Day2908/Exercise1.cs new file mode 100644 index 0000000..a1bbc7c --- /dev/null +++ b/Topic5_BinarySearch/Day2908/Exercise1.cs @@ -0,0 +1,40 @@ +//https://leetcode.com/problems/binary-search/ + +/* ++ Using binary search technique ++ Find the element at the middle of array + + If that element equals to target => return true + + If that element is smaller than target => that element on left side + + Otherwise => that element on right side + +Space complexity: O(1) +Time complexity: O(logN) +*/ + +namespace Day2908 +{ + public class Exercise1 + { + public int Search(int[] nums, int target) + { + int result = -1; + + int left = 0; + int right = nums.Length - 1; + + while (left <= right) + { + int mid = left + (right - left) / 2; + + if (nums[mid] == target) + return mid; + else if (nums[mid] > target) + right = mid - 1; + else + left = mid + 1; + } + + return result; + } + } +} \ No newline at end of file diff --git a/Topic5_BinarySearch/Day2908/Exercise2.cs b/Topic5_BinarySearch/Day2908/Exercise2.cs new file mode 100644 index 0000000..d5109c9 --- /dev/null +++ b/Topic5_BinarySearch/Day2908/Exercise2.cs @@ -0,0 +1,78 @@ +//https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/ + +/* ++ Step 1: work to find the first suitable result (lower_bound) + + If the middle element is smaller than target value => move to right + + If the middle element is higher than or equals target value + => move to left + => Assign to first idx if middle element equals to target value ++ Step 2: work to find the second suitable result (upper_bound) + + If the middle element is smaller than or equals target value + => move to right + => Assign to second idx if middle element equals to target value + + + If the middle element is higher than target value + => move to left + +Space complexity: O(1) +Time complexity: O(logN) +*/ +namespace Day2908 +{ + public class Exercise2 + { + public int[] SearchRange(int[] nums, int target) + { + int[] result = new int[2]; + result[0] = -1; + result[1] = -1; + + if (nums.Length == 0) return result; + + //Step 1: work to find the first suitable result + int left = 0; + int right = nums.Length - 1; + + while (left <= right) + { + int mid = left + (right - left) / 2; + + if (nums[mid] >= target) + { + right = mid - 1; + if (nums[mid] == target) + result[0] = mid; + } + else + { + left = mid + 1; + } + } + + if (result[0] == -1) return result; + + //Step 2: work to find the second suitable result + left = 0; + right = nums.Length - 1; + + while (left <= right) + { + int mid = left + (right - left) / 2; + + if (nums[mid] <= target) + { + left = mid + 1; + if (nums[mid] == target) + result[1] = mid; + } + else + { + right = mid - 1; + } + } + + + return result; + } + } +} \ No newline at end of file From 2a8f8f5705c7593257f8c360b2db96a0b2b8fd2a Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Fri, 30 Aug 2024 10:10:11 +0700 Subject: [PATCH 28/39] tutantai0708 - Day3008 --- Topic5_BinarySearch/Day3008/Exercise1.cs | 36 ++++++++++++++++++++++ Topic5_BinarySearch/Day3008/Exercise2.cs | 33 ++++++++++++++++++++ Topic5_BinarySearch/Day3008/Exercise3.cs | 39 ++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 Topic5_BinarySearch/Day3008/Exercise1.cs create mode 100644 Topic5_BinarySearch/Day3008/Exercise2.cs create mode 100644 Topic5_BinarySearch/Day3008/Exercise3.cs diff --git a/Topic5_BinarySearch/Day3008/Exercise1.cs b/Topic5_BinarySearch/Day3008/Exercise1.cs new file mode 100644 index 0000000..8fd2dc9 --- /dev/null +++ b/Topic5_BinarySearch/Day3008/Exercise1.cs @@ -0,0 +1,36 @@ +//https://leetcode.com/problems/sqrtx/ + +/* ++ Using binary search technique ++ Find the element at the middle of array + + If that element multiples together is lower than or equals to target => move to right to search + + Otherwise => move to left to search + +Space complexity: O(1) +Time complexity: O(logN) +*/ + +namespace Day3008 +{ + public class Exercise1 + { + public int MySqrt(int x) + { + long left = 1; + long right = x; + + while (left <= right) + { + long mid = left + (right - left) / 2; + long val = mid * mid; + + if (val <= x) + left = mid + 1; + else + right = mid - 1; + } + + return (int)right; + } + } +} \ No newline at end of file diff --git a/Topic5_BinarySearch/Day3008/Exercise2.cs b/Topic5_BinarySearch/Day3008/Exercise2.cs new file mode 100644 index 0000000..00374a3 --- /dev/null +++ b/Topic5_BinarySearch/Day3008/Exercise2.cs @@ -0,0 +1,33 @@ +//https://leetcode.com/problems/first-bad-version/ + +/* ++ Using binary search technique ++ Find the element at the middle of array + + If that element is a bad version => move to left to search + + Otherwise => move to right to search + +Space complexity: O(1) +Time complexity: O(logN) +*/ + +namespace Day3008 +{ + public class Exercise2 + { + public int FirstBadVersion(int n) + { + int left = 1; + int right = n; + + while (left <= right) + { + int mid = left + (right - left) / 2; + if (IsBadVersion(mid)) + right = mid - 1; + else + left = mid + 1; + } + return left; + } + } +} \ No newline at end of file diff --git a/Topic5_BinarySearch/Day3008/Exercise3.cs b/Topic5_BinarySearch/Day3008/Exercise3.cs new file mode 100644 index 0000000..0870f6a --- /dev/null +++ b/Topic5_BinarySearch/Day3008/Exercise3.cs @@ -0,0 +1,39 @@ +//https://leetcode.com/problems/valid-perfect-square/ + +/* ++ Using binary search technique ++ Find the element at the middle of array + + If that element multiples together equals to target => return true + + If that element multiples together is lower than target => move to right to search + + Otherwise => move to left to search + +Space complexity: O(1) +Time complexity: O(logN) +*/ + +namespace Day3008 +{ + public class Exercise3 + { + public bool IsPerfectSquare(int num) + { + Int64 left = 1; + Int64 right = num; + + while (left <= right) + { + Int64 mid = left + (right - left) / 2; + + Int64 temp = mid * mid; + + if (temp == num) + return true; + else if (temp < num) + left = mid + 1; + else + right = mid - 1; + } + return false; + } + } +} \ No newline at end of file From c55076f95d9abab125d5556ee37dbab4e1547ad9 Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Sun, 1 Sep 2024 06:30:59 +0700 Subject: [PATCH 29/39] tuantai0708 - Day3108 --- Topic5_BinarySearch/Day3108/Exercise1.cs | 44 ++++++++++++++++++++++ Topic5_BinarySearch/Day3108/Exercise2.cs | 47 ++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 Topic5_BinarySearch/Day3108/Exercise1.cs create mode 100644 Topic5_BinarySearch/Day3108/Exercise2.cs diff --git a/Topic5_BinarySearch/Day3108/Exercise1.cs b/Topic5_BinarySearch/Day3108/Exercise1.cs new file mode 100644 index 0000000..386fa00 --- /dev/null +++ b/Topic5_BinarySearch/Day3108/Exercise1.cs @@ -0,0 +1,44 @@ +//https://leetcode.com/problems/search-a-2d-matrix + +/* ++ Using binary search technique ++ Find the element at the middle of 2d array ++ To access valid position in 2d array => [mid / col][mid % col] + + If that element equals to target => return true + + If that element is smaller than target => that element on left side + + Otherwise => that element on right side + +Space complexity: O(1) +Time complexity: O(logN) +*/ + +namespace Day3108 +{ + public class Exercise1 + { + public bool SearchMatrix(int[][] matrix, int target) + { + int row = matrix.Length; + int col = matrix[0].Length; + + int Length = row * col; + + int left = 0; + int right = Length - 1; + + while (left <= right) + { + int mid = left + (right - left) / 2; + + if (matrix[mid / col][mid % col] == target) + return true; + else if (matrix[mid / col][mid % col] > target) + right = mid - 1; + else + left = mid + 1; + } + + return false; + } + } +} \ No newline at end of file diff --git a/Topic5_BinarySearch/Day3108/Exercise2.cs b/Topic5_BinarySearch/Day3108/Exercise2.cs new file mode 100644 index 0000000..762dfd7 --- /dev/null +++ b/Topic5_BinarySearch/Day3108/Exercise2.cs @@ -0,0 +1,47 @@ +//https://leetcode.com/problems/koko-eating-bananas/ + +/* ++ Using binary search technique (range from [1, Max]) ++ To access middle position of that range + + After calculating how many bananas can eat within a hour + => If that value is smaller than h => move to left to search + => Otherwise => move to right to search + +Space complexity: O(1) +Time complexity: O(log(maxi) * N) +*/ + + +namespace Day3108 +{ + public class Exercise2 + { + public int MinEatingSpeed(int[] piles, int h) + { + int left = 1; + int right = piles.Max(); + + while (left <= right) + { + int mid = left + (right - left) / 2; + long calc = _countBananaWithInHours(piles, mid); + + if (calc <= h) + right = mid - 1; + else + left = mid + 1; + } + + return left; + } + + private long _countBananaWithInHours(int[] piles, int k) + { + long result = 0; + foreach (int pile in piles) + result += pile % k == 0 ? pile / k : (pile / k) + 1; + + return result; + } + } +} \ No newline at end of file From 4aab03198398cdbd11ac52b960378f354cbb715a Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Mon, 2 Sep 2024 08:19:30 +0700 Subject: [PATCH 30/39] tuantai0708 - Day0109 --- Topic5_BinarySearch/Day0109/Exercise1.cs | 52 +++++++++++++++++++++++ Topic5_BinarySearch/Day0109/Exercise2.cs | 47 +++++++++++++++++++++ Topic5_BinarySearch/Day0109/Exercise3.cs | 54 ++++++++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 Topic5_BinarySearch/Day0109/Exercise1.cs create mode 100644 Topic5_BinarySearch/Day0109/Exercise2.cs create mode 100644 Topic5_BinarySearch/Day0109/Exercise3.cs diff --git a/Topic5_BinarySearch/Day0109/Exercise1.cs b/Topic5_BinarySearch/Day0109/Exercise1.cs new file mode 100644 index 0000000..3c4380a --- /dev/null +++ b/Topic5_BinarySearch/Day0109/Exercise1.cs @@ -0,0 +1,52 @@ +//https://leetcode.com/problems/search-in-rotated-sorted-array/ + +/* ++ Using binary search technique ++ Find the element at the middle of 2d array ++ If left half is sorted + + If target is in the range of left half => move to left + + Otherwise => move to right ++ If right half is sorted + + If target is in the range of right half => move to right + + Otherwise => move to left + +Space complexity: O(1) +Time complexity: O(logN) +*/ + +namespace Day0109 +{ + public class Exercise1 + { + public int Search(int[] nums, int target) + { + int left = 0; + int right = nums.Length - 1; + + while (left <= right) + { + int mid = left + (right - left) / 2; + if (nums[mid] == target) + return mid; + //left is sorted + else if (nums[left] <= nums[mid]) + { + if (nums[left] <= target && target <= nums[mid]) + right = mid - 1; + else + left = mid + 1; + } + //right is sorted + else + { + if (nums[mid] <= target && target <= nums[right]) + left = mid + 1; + else + right = mid - 1; + } + + } + return -1; + } + } +} \ No newline at end of file diff --git a/Topic5_BinarySearch/Day0109/Exercise2.cs b/Topic5_BinarySearch/Day0109/Exercise2.cs new file mode 100644 index 0000000..93d22cc --- /dev/null +++ b/Topic5_BinarySearch/Day0109/Exercise2.cs @@ -0,0 +1,47 @@ +//https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/ + +/* ++ Using binary search technique ++ Find the element at the middle of 2d array ++ If left half is sorted + => Assign the minimum value at left position into mini variable + => move to right to search ++ If right half is sorted + => Assign the minimum value at mid position into mini variable + => move to left to search + +Space complexity: O(1) +Time complexity: O(logN) +*/ + +namespace Day0109 +{ + public class Exercise2 + { + public int FindMin(int[] nums) + { + int left = 0; + int right = nums.Length - 1; + int mini = Int32.MaxValue; + + while (left <= right) + { + int mid = left + (right - left) / 2; + + if (nums[left] <= nums[mid]) + { + mini = Math.Min(mini, nums[left]); + left = mid + 1; + } + else + { + mini = Math.Min(mini, nums[mid]); + right = mid - 1; + } + + } + + return mini; + } + } +} \ No newline at end of file diff --git a/Topic5_BinarySearch/Day0109/Exercise3.cs b/Topic5_BinarySearch/Day0109/Exercise3.cs new file mode 100644 index 0000000..ef4cc50 --- /dev/null +++ b/Topic5_BinarySearch/Day0109/Exercise3.cs @@ -0,0 +1,54 @@ +//https://leetcode.com/problems/find-peak-element/ + +/* ++ Using binary search technique ++ Eliminate the first and last position + ++ Find the element at the middle of 2d array ++ If that element is the peek element + => return that position ++ At mid position, if left neighbor is smaller than right neighbor + => move to right neighbor to get larger element ++ At mid position, if left neighbor is higher than right neighbor + => move to left neighbor to get larger element + +Space complexity: O(1) +Time complexity: O(logN) +*/ + +namespace Day0109 +{ + public class Exercise3 + { + public int FindPeakElement(int[] nums) + { + int Length = nums.Length; + + if (Length == 1) return 0; + + //eliminate the first and last position + if (nums[0] > nums[1]) + return 0; + + if (nums[Length - 1] > nums[Length - 2]) + return Length - 1; + + int left = 1; + int right = Length - 2; + + while (left <= right) + { + int mid = left + (right - left) / 2; + + if (nums[mid - 1] < nums[mid] && nums[mid] > nums[mid + 1]) + return mid; + else if (nums[mid - 1] < nums[mid]) + left = mid + 1; + else + right = mid - 1; + } + + return -1; + } + } +} \ No newline at end of file From 930e10b8c5843f1c7a4cd3e519c7b595c102d929 Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Mon, 2 Sep 2024 09:09:55 +0700 Subject: [PATCH 31/39] tuantai0708 - Day0209 --- Topic5_BinarySearch/Day0209/Exercise1.cs | 40 +++++++++++++ Topic5_BinarySearch/Day0209/Exercise2.cs | 72 ++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 Topic5_BinarySearch/Day0209/Exercise1.cs create mode 100644 Topic5_BinarySearch/Day0209/Exercise2.cs diff --git a/Topic5_BinarySearch/Day0209/Exercise1.cs b/Topic5_BinarySearch/Day0209/Exercise1.cs new file mode 100644 index 0000000..a8e222a --- /dev/null +++ b/Topic5_BinarySearch/Day0209/Exercise1.cs @@ -0,0 +1,40 @@ +//https://leetcode.com/problems/arranging-coins/ + +/* ++ Using binary search technique + ++ Find the element at the middle of array + + If that element equals to target => return currentSum + + If that element is smaller than target => that element on right side + + Otherwise => that element on left side + +Space complexity: O(1) +Time complexity: O(logN) +*/ + +namespace Day0209 +{ + public class Exercise1 + { + public int ArrangeCoins(int n) + { + int left = 1; + int right = n; + + while (left <= right) + { + int mid = left + (right - left) / 2; + long currentSum = (long)mid * (mid + 1) / 2; + + if (currentSum == n) + return mid; + else if (currentSum < n) + left = mid + 1; + else + right = mid - 1; + } + + return right; + } + } +} \ No newline at end of file diff --git a/Topic5_BinarySearch/Day0209/Exercise2.cs b/Topic5_BinarySearch/Day0209/Exercise2.cs new file mode 100644 index 0000000..13a139d --- /dev/null +++ b/Topic5_BinarySearch/Day0209/Exercise2.cs @@ -0,0 +1,72 @@ +//https://leetcode.com/problems/time-based-key-value-store/ + +/* ++ Because when wet set a new element based on key, the timestamp will be larger than the last one ++ Using binary search technique to search + ++ Find the element at the middle of list based on key + + If that element is smaller than or equals to target + => assign current key to result + => that element on right side + + If that element is smaller than target => that element on left side + +Space complexity: O(1) +Time complexity: O(logN) +*/ + +namespace Day0209 +{ + public class Exercise2 + { + public class TimeMap + { + Dictionary>> dictionary; + public TimeMap() + { + dictionary = new(); + } + + public void Set(string key, string value, int timestamp) + { + if (dictionary.ContainsKey(key)) + dictionary[key].Add(new KeyValuePair(value, timestamp)); + else + { + dictionary[key] = new List>(); + dictionary[key].Add(new KeyValuePair(value, timestamp)); + } + } + + public string Get(string key, int timestamp) + { + if (!dictionary.ContainsKey(key)) + return ""; + else + { + List> temp = dictionary[key]; + + //run binary search + int left = 0; + int right = temp.Count - 1; + + string result = ""; + + while (left <= right) + { + int mid = left + (right - left) / 2; + + if (temp[mid].Value <= timestamp) + { + result = temp[mid].Key; + left = mid + 1; + } + else + right = mid - 1; + } + + return result; + } + } + } + } +} \ No newline at end of file From 3df858a289f90cb3c8831cb164274f85c038fefd Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Wed, 4 Sep 2024 10:24:53 +0700 Subject: [PATCH 32/39] tuantai0708 - Day0309 --- Topic6-Sorting/Day0309/Exercise1.cs | 37 ++++++++++++++++ Topic6-Sorting/Day0309/Exercise2.cs | 68 +++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 Topic6-Sorting/Day0309/Exercise1.cs create mode 100644 Topic6-Sorting/Day0309/Exercise2.cs diff --git a/Topic6-Sorting/Day0309/Exercise1.cs b/Topic6-Sorting/Day0309/Exercise1.cs new file mode 100644 index 0000000..e26805f --- /dev/null +++ b/Topic6-Sorting/Day0309/Exercise1.cs @@ -0,0 +1,37 @@ +//https://leetcode.com/problems/merge-sorted-array/description/ + +/* ++ Using 2 pointers ++ When comparing 2 elements in 2 arrays + => push the larger element at the end + ++ Assign the leftover element of second array into first array + +Space complexity: O(1) +Time complexity: O(M + N) +*/ + +namespace Day0309 +{ + public class Exercise1 + { + public void Merge(int[] nums1, int m, int[] nums2, int n) + { + int i = m - 1; + int j = n - 1; + int k = nums1.Length - 1; + + while (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--]; + + } + } +} \ No newline at end of file diff --git a/Topic6-Sorting/Day0309/Exercise2.cs b/Topic6-Sorting/Day0309/Exercise2.cs new file mode 100644 index 0000000..a12c89b --- /dev/null +++ b/Topic6-Sorting/Day0309/Exercise2.cs @@ -0,0 +1,68 @@ +//https://leetcode.com/problems/sort-an-array/description/ + +/* ++ Using merge sort technique ++ Divide arr into 2 half and sort every half ++ After that, merge 2 half together => become an sorted array + +Space complexity: O(N) +Time complexity: O(NlogN) +*/ + +namespace Day0309 +{ + public class Exercise2 + { + public int[] SortArray(int[] nums) + { + MergeSort(nums, 0, nums.Length - 1); + return nums; + } + + private void MergeSort(int[] nums, int left, int right) + { + if (left == right) + return; + + int mid = left + (right - left) / 2; + + MergeSort(nums, left, mid); + MergeSort(nums, mid + 1, right); + Merge(nums, left, mid, right); + } + + private void Merge(int[] nums, int left, int mid, int right) + { + int m = mid - left + 1; + int n = right - mid; + + int[] leftArr = new int[m]; + int[] rightArr = new int[n]; + + for (int z = 0; z < m; ++z) + leftArr[z] = nums[left + z]; + + for (int z = 0; z < n; ++z) + rightArr[z] = nums[mid + 1 + z]; + + int i = 0; + int j = 0; + int k = left; + + while (i < m && j < n) + { + if (leftArr[i] >= rightArr[j]) + nums[k++] = rightArr[j++]; + else + nums[k++] = leftArr[i++]; + } + + while (i < m) + nums[k++] = leftArr[i++]; + + while (j < n) + nums[k++] = rightArr[j++]; + + } + } +} \ No newline at end of file From 135d3f0b3d93765c39b7c15bb003bccca3db37c2 Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Thu, 5 Sep 2024 05:47:50 +0700 Subject: [PATCH 33/39] tuantai0708 - Day0409 --- Topic6-Sorting/Day0409/Exercise1.cs | 67 +++++++++++++++++++++++++++++ Topic6-Sorting/Day0409/Exercise2.cs | 55 +++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 Topic6-Sorting/Day0409/Exercise1.cs create mode 100644 Topic6-Sorting/Day0409/Exercise2.cs diff --git a/Topic6-Sorting/Day0409/Exercise1.cs b/Topic6-Sorting/Day0409/Exercise1.cs new file mode 100644 index 0000000..cda2360 --- /dev/null +++ b/Topic6-Sorting/Day0409/Exercise1.cs @@ -0,0 +1,67 @@ +//https://leetcode.com/problems/pancake-sorting/ + +/* ++ To start with the largest element in array + + Find idx contaning that element and flip to the front + + Flip again to make it at the end + + To decrease larger element and continue looping + +Space complexity: O(1) +Time complexity: O(N ^ 2) +*/ + +namespace Day0409 +{ + public class Exercise1 + { + public IList PancakeSort(int[] arr) + { + int Length = arr.Length; + + List result = new List(); + + int count = 0; + for (int i = Length; i > 1; --i) + { + int maxIndex = _findMaxIdxFrom0ToN(arr, i); + + if (maxIndex != i - 1) + { + _flip(arr, maxIndex + 1); + result.Add(maxIndex + 1); + + _flip(arr, i); + result.Add(i); + } + } + + return result; + } + + private int _findMaxIdxFrom0ToN(int[] arr, int n) + { + int maxIdx = 0; + + for (int i = 1; i < n; ++i) + { + if (arr[i] > arr[maxIdx]) + maxIdx = i; + } + return maxIdx; + } + private void _flip(int[] arr, int k) + { + int left = 0; + int right = k - 1; + + while (left < right) + { + int temp = arr[left]; + arr[left] = arr[right]; + arr[right] = temp; + ++left; + --right; + } + } + } +} \ No newline at end of file diff --git a/Topic6-Sorting/Day0409/Exercise2.cs b/Topic6-Sorting/Day0409/Exercise2.cs new file mode 100644 index 0000000..447c8b2 --- /dev/null +++ b/Topic6-Sorting/Day0409/Exercise2.cs @@ -0,0 +1,55 @@ +//https://leetcode.com/problems/sort-colors/ + +/* ++ Using 3 pointers + + Left pointer: [0, left - 1] is 0 value + + Mid pointer: to iterate + + Right Pointer [Right + 1, Length - 1] is 2 value + ++ When looping with arr we will have 3 value + + With 0: swap current mid pointer with left pointer => increate top, mid pointer + + With 1: ignore that + + With 2: swap current mid pointer with right pointer => decrease right pointer + +Space complexity: O(1) +Time complexity: O(N) +*/ + +namespace Day0409 +{ + public class Exercise2 + { + public void SortColors(int[] nums) + { + int red = 0; + int white = 0; + int blue = nums.Length - 1; + + while (white <= blue) + { + if (nums[white] == 0) + { + Swap(ref nums[red], ref nums[white]); + ++red; + ++white; + } + else if (nums[white] == 1) + { + ++white; + } + else + { + Swap(ref nums[white], ref nums[blue]); + --blue; + } + } + } + + private void Swap(ref int a, ref int b) + { + int temp = a; + a = b; + b = temp; + } + } +} \ No newline at end of file From 450cb6bf6b97b4931482cece952c3acff212fca4 Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Fri, 6 Sep 2024 06:50:20 +0700 Subject: [PATCH 34/39] tuantai0708 - Day0509 --- Topic6-Sorting/Day0509/Exercise1.cs | 57 +++++++++++++++++++++++++++++ Topic6-Sorting/Day0509/Exercise2.cs | 29 +++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 Topic6-Sorting/Day0509/Exercise1.cs create mode 100644 Topic6-Sorting/Day0509/Exercise2.cs diff --git a/Topic6-Sorting/Day0509/Exercise1.cs b/Topic6-Sorting/Day0509/Exercise1.cs new file mode 100644 index 0000000..781a7bc --- /dev/null +++ b/Topic6-Sorting/Day0509/Exercise1.cs @@ -0,0 +1,57 @@ +//https://leetcode.com/problems/sort-an-array/ + +/* ++ To get the last element of array as pivot + + To move all elements less than pivot on the left + + To move all elements greater than pivot on the right + + To move that pivot element at the right position + +Space complexity: O(N) +Time complexity: O(N ^ 2) +*/ +namespace Day0509 +{ + public class Exercise1 + { + public int[] SortArray(int[] nums) + { + _quickSort(nums, 0, nums.Length - 1); + + return nums; + } + + private void _quickSort(int[] nums, int start, int end) + { + if (start >= end) return; + + int pivot = _partition(nums, start, end); + _quickSort(nums, start, pivot - 1); + _quickSort(nums, pivot + 1, end); + } + + private int _partition(int[] nums, int start, int end) + { + int i = start - 1; + int j = start; + + while (j < end) + { + if (nums[j] < nums[end]) + _swap(ref nums[++i], ref nums[j]); + + j++; + } + + _swap(ref nums[++i], ref nums[j]); + + return i; + } + + private void _swap(ref int a, ref int b) + { + int temp = a; + a = b; + b = temp; + } + } +} \ No newline at end of file diff --git a/Topic6-Sorting/Day0509/Exercise2.cs b/Topic6-Sorting/Day0509/Exercise2.cs new file mode 100644 index 0000000..c3bb28a --- /dev/null +++ b/Topic6-Sorting/Day0509/Exercise2.cs @@ -0,0 +1,29 @@ +//https://leetcode.com/problems/largest-number/ + +/* ++ To sort array based on adding 2 strings + +Space complexity: O(N) +Time complexity: O(N logN) +*/ + +namespace Day0509 +{ + public class Exercise2 + { + public string LargestNumber(int[] nums) + { + if (nums.All(num => num == 0)) return "0"; + + Array.Sort(nums, (a, b) => + { + string strA = a.ToString(); + string strB = b.ToString(); + + return -(strA + strB).CompareTo(strB + strA); + + }); + return string.Concat(nums); + } + } +} \ No newline at end of file From ed38b93d93c208f6049f6cefb4d37ae26f653ee7 Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Sat, 7 Sep 2024 06:56:23 +0700 Subject: [PATCH 35/39] tuantai0708 - Day0609 --- Topic6-Sorting/Day0609/Exercise1.cs | 48 +++++++++++++++++ Topic6-Sorting/Day0609/Exercise2.cs | 83 +++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 Topic6-Sorting/Day0609/Exercise1.cs create mode 100644 Topic6-Sorting/Day0609/Exercise2.cs diff --git a/Topic6-Sorting/Day0609/Exercise1.cs b/Topic6-Sorting/Day0609/Exercise1.cs new file mode 100644 index 0000000..818ae40 --- /dev/null +++ b/Topic6-Sorting/Day0609/Exercise1.cs @@ -0,0 +1,48 @@ +//https://leetcode.com/problems/merge-two-sorted-lists/ + +/* ++ To use 2 pointers technique + + if a value of first pointer is larger than a value of second pointer + => add value of second pointer into result + => move forward that second pointer + + Otherwise + => add value of first pointer into result + => move forward that first pointer + +Space complexity: O(1) +Time complexity: O(Max(M, N)) +*/ + +namespace Day0609 +{ + public class Exercise1 + { + public ListNode MergeTwoLists(ListNode list1, ListNode list2) + { + ListNode dummyNode = new(-1); + ListNode result = dummyNode; + + while (list1 != null || list2 != null) + { + int val1 = list1 != null ? list1.val : Int32.MaxValue; + int val2 = list2 != null ? list2.val : Int32.MaxValue; + + ListNode temp = new(-1); + if (val1 >= val2) + { + temp = new(val2); + if (list2 != null) list2 = list2.next; + } + else + { + temp = new(val1); + if (list1 != null) list1 = list1.next; + } + dummyNode.next = temp; + dummyNode = dummyNode.next; + } + + return result.next; + } + } +} \ No newline at end of file diff --git a/Topic6-Sorting/Day0609/Exercise2.cs b/Topic6-Sorting/Day0609/Exercise2.cs new file mode 100644 index 0000000..211273c --- /dev/null +++ b/Topic6-Sorting/Day0609/Exercise2.cs @@ -0,0 +1,83 @@ +//https://leetcode.com/problems/sort-list/ + +/* ++ To use merge sort technique + + To get the middle element of linked list + + To run recursive call on left + + To run recursive call on right + + Merge them toegether + +Space complexity: O(log N * (N + N / 2)) recursive stack space +Time complexity: O(N LogN) +*/ + +namespace Day0609 +{ + public class Exercise2 + { + public ListNode SortList(ListNode head) + { + return _mergeSort(head); + } + + private ListNode _mergeSort(ListNode head) + { + if (head == null || head.next == null) + return head; + + ListNode middle = _findMiddleNode(head); + + ListNode leftHead = head; + ListNode rightHead = middle.next; + + middle.next = null; + + leftHead = _mergeSort(leftHead); + rightHead = _mergeSort(rightHead); + + return _merge(leftHead, rightHead); + } + + private ListNode _findMiddleNode(ListNode head) + { + ListNode slow = head; + ListNode fast = head.next; + + while (slow != null && fast != null && fast.next != null) + { + slow = slow.next; + fast = fast.next.next; + } + + return slow; + } + + private ListNode _merge(ListNode list1, ListNode list2) + { + ListNode dummyNode = new(-1); + ListNode result = dummyNode; + + while (list1 != null || list2 != null) + { + int val1 = list1 != null ? list1.val : Int32.MaxValue; + int val2 = list2 != null ? list2.val : Int32.MaxValue; + + ListNode temp = new(-1); + if (val1 >= val2) + { + temp = new(val2); + if (list2 != null) list2 = list2.next; + } + else + { + temp = new(val1); + if (list1 != null) list1 = list1.next; + } + dummyNode.next = temp; + dummyNode = dummyNode.next; + } + + return result.next; + } + } +} \ No newline at end of file From f1599cce9a0176c4eaed42c50245e8966a0f3c88 Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Sat, 7 Sep 2024 07:16:51 +0700 Subject: [PATCH 36/39] tuantai0708 - Day0709 --- Topic6-Sorting/Day0709/Exercise1.cs | 44 ++++++++++++++++++++++++++ Topic6-Sorting/Day0709/Exercise2.cs | 48 +++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 Topic6-Sorting/Day0709/Exercise1.cs create mode 100644 Topic6-Sorting/Day0709/Exercise2.cs diff --git a/Topic6-Sorting/Day0709/Exercise1.cs b/Topic6-Sorting/Day0709/Exercise1.cs new file mode 100644 index 0000000..4ba7477 --- /dev/null +++ b/Topic6-Sorting/Day0709/Exercise1.cs @@ -0,0 +1,44 @@ +//https://leetcode.com/problems/sort-characters-by-frequency/ + +/* ++ To count the frequency of every character in dictionary ++ To sort based on that dictionary + + If the frequeny of 2 elements is different => sort on that frequency + + Otherwise => sort based on alphabet + +Space complexity: O(N) +Time complexity: O(NlogN) +*/ + +namespace Day0709 +{ + public class Exercise1 + { + public string FrequencySort(string str) + { + Dictionary dict = new(); + foreach (char s in str) + { + if (dict.ContainsKey(s)) + dict[s]++; + else + dict[s] = 1; + } + + char[] charArray = str.ToCharArray(); + + Array.Sort(charArray, (x, y) => + { + int val1 = dict[x]; + int val2 = dict[y]; + + if (val1 != val2) + return val2.CompareTo(val1); + + return x.CompareTo(y); + + }); + return new string(charArray); + } + } +} \ No newline at end of file diff --git a/Topic6-Sorting/Day0709/Exercise2.cs b/Topic6-Sorting/Day0709/Exercise2.cs new file mode 100644 index 0000000..5f6bf5c --- /dev/null +++ b/Topic6-Sorting/Day0709/Exercise2.cs @@ -0,0 +1,48 @@ +//https://leetcode.com/problems/merge-intervals/description/ + +/* ++ To sort 2d array based on first element of array ++ To get the first array as based condition ++ To loop from the second array and compare to value of 2 elements in the first array + + If it's overlapping => update value of the current first and second element + + Otherwise => add current first and second element into result and update a new one + +Space complexity: O(N) +Time complexity: O(NLogN) +*/ + +namespace Day0709 +{ + public class Exercise2 + { + public int[][] Merge(int[][] intervals) + { + Array.Sort(intervals, (row1, row2) => row1[0].CompareTo(row2[0])); + + List result = new(); + + int first = intervals[0][0]; + int second = intervals[0][1]; + + for (int i = 1; i < intervals.Length; ++i) + { + if (first <= intervals[i][0] && intervals[i][0] <= second) + { + first = Math.Min(first, intervals[i][0]); + second = Math.Max(second, intervals[i][1]); + } + else + { + result.Add([first, second]); + + first = intervals[i][0]; + second = intervals[i][1]; + } + } + + result.Add([first, second]); + + return result.ToArray(); + } + } +} \ No newline at end of file From cc720b1306e42a7f114b5f910f13f977813ece69 Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Wed, 11 Sep 2024 07:48:09 +0700 Subject: [PATCH 37/39] tuantai0708 - Day1109 --- Topic7-HashTable/Day1109/Exercise1.cs | 41 ++++++++++++++++++++++++ Topic7-HashTable/Day1109/Exercise2.cs | 45 +++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 Topic7-HashTable/Day1109/Exercise1.cs create mode 100644 Topic7-HashTable/Day1109/Exercise2.cs diff --git a/Topic7-HashTable/Day1109/Exercise1.cs b/Topic7-HashTable/Day1109/Exercise1.cs new file mode 100644 index 0000000..5baf4dc --- /dev/null +++ b/Topic7-HashTable/Day1109/Exercise1.cs @@ -0,0 +1,41 @@ +//https://leetcode.com/problems/design-hashmap/ + +/* ++ Using map technique ++ Because value is -1 as can not find => we will add 1 value when adding key into map array ++ And remove 1 value when getting that value from array +Space complexity: O(10000000) +Time complexity: O(1) +*/ +namespace Day1109 +{ + public class Exercise1 + { + public class MyHashMap + { + readonly int[] map; + public MyHashMap() + { + map = new int[10000000]; + } + + public void Put(int key, int value) + { + map[key] = value + 1; + } + + public int Get(int key) + { + return map[key] - 1; + } + + public void Remove(int key) + { + //0 is treated as no key present + map[key] = 0; + } + } + } +} + + diff --git a/Topic7-HashTable/Day1109/Exercise2.cs b/Topic7-HashTable/Day1109/Exercise2.cs new file mode 100644 index 0000000..6702949 --- /dev/null +++ b/Topic7-HashTable/Day1109/Exercise2.cs @@ -0,0 +1,45 @@ +//https://leetcode.com/problems/max-number-of-k-sum-pairs/ + +/* ++ Using dictionary technique + ++ when iterating one element in array, I can check after substracting k with that element ++ If result is contained in array => answer and substract one value of that key in dictionary ++ Otherwise => add element into dictionary + +Space complexity: O(N) +Time complexity: O(N) +*/ + +namespace Day1109 +{ + public class Exercise2 + { + public int MaxOperations(int[] nums, int k) + { + Dictionary dict = new(); + int result = 0; + + foreach (int num in nums) + { + int count = k - num; + if (dict.TryGetValue(count, out int value1)) + { + ++result; + dict[count] = --value1; + + if (value1 == 0) + dict.Remove(count); + } + else + { + if (dict.TryGetValue(num, out int value2)) + dict[num] = ++value2; + else + dict[num] = 1; + } + } + return result; + } + } +} \ No newline at end of file From 305874f7b58c35b37c1ed97e79a1ca5092551e51 Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Thu, 12 Sep 2024 07:40:08 +0700 Subject: [PATCH 38/39] tuantai0708 - Day1209 --- Topic7-HashTable/Day1209/Exercise1.cs | 51 +++++++++++++++++++++++++++ Topic7-HashTable/Day1209/Exercise2.cs | 36 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 Topic7-HashTable/Day1209/Exercise1.cs create mode 100644 Topic7-HashTable/Day1209/Exercise2.cs diff --git a/Topic7-HashTable/Day1209/Exercise1.cs b/Topic7-HashTable/Day1209/Exercise1.cs new file mode 100644 index 0000000..0ddcad8 --- /dev/null +++ b/Topic7-HashTable/Day1209/Exercise1.cs @@ -0,0 +1,51 @@ +using System.Text; + +//https://leetcode.com/problems/group-anagrams/ + +/* ++ Using dictionary technique + + Key: string to store element and a number of its frequency in array + + Value: string corresponds to that key +Space complexity: O(N) +Time complexity: O(N * (M + 26)) +*/ + +namespace Day1209 +{ + public class Exercise1 + { + public IList> GroupAnagrams(string[] strs) + { + Dictionary> dict = []; + + foreach (string str in strs) + { + int[] charArr = new int[26]; + + foreach (char c in str) + charArr[c - 'a']++; + + StringBuilder temp = new(); + + for (int i = 0; i < 26; ++i) + { + char letter = (char)('a' + i); + + if (charArr[i] != 0) + { + temp.Append(charArr[i]); + temp.Append(letter); + } + + } + if (!dict.ContainsKey(temp.ToString())) + dict[temp.ToString()] = []; + + dict[temp.ToString()].Add(str); + + } + + return new List>(dict.Values); + } + } +} \ No newline at end of file diff --git a/Topic7-HashTable/Day1209/Exercise2.cs b/Topic7-HashTable/Day1209/Exercise2.cs new file mode 100644 index 0000000..a5d6e2f --- /dev/null +++ b/Topic7-HashTable/Day1209/Exercise2.cs @@ -0,0 +1,36 @@ +//https://leetcode.com/problems/continuous-subarray-sum/ + +/* ++ Using dictionary technique + + Key: int type to store value that get total % k + + Value: idx coresponds to that key (idx is farthest) +Space complexity: O(N) +Time complexity: O(N) +*/ + +namespace Day1209 +{ + public class Exercise2 + { + public bool CheckSubarraySum(int[] nums, int k) + { + int total = 0; + Dictionary dict = []; + + dict[0] = -1; + int Length = nums.Length; + for (int i = 0; i < Length; ++i) + { + total += nums[i]; + + int count = total % k; + + if (!dict.ContainsKey(count)) + dict[count] = i; + else if (i - dict[count] >= 2) + return true; + } + return false; + } + } +} \ No newline at end of file From e9cac60cbbb0694f995af504c8c845c83a81025a Mon Sep 17 00:00:00 2001 From: tuantai0708 Date: Fri, 13 Sep 2024 08:01:28 +0700 Subject: [PATCH 39/39] tuantai0708 - Day1309 --- Topic7-HashTable/Day1309/Exercise1.cs | 41 +++++++++++++++++++++++++++ Topic7-HashTable/Day1309/Exercise2.cs | 40 ++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 Topic7-HashTable/Day1309/Exercise1.cs create mode 100644 Topic7-HashTable/Day1309/Exercise2.cs diff --git a/Topic7-HashTable/Day1309/Exercise1.cs b/Topic7-HashTable/Day1309/Exercise1.cs new file mode 100644 index 0000000..6bac946 --- /dev/null +++ b/Topic7-HashTable/Day1309/Exercise1.cs @@ -0,0 +1,41 @@ +//https://leetcode.com/problems/subarray-sum-equals-k/ + +/* ++ Using dictionary technique + + Key: to store sum of elements at idx i + + Value: to store frequency of that sum at idx i +Space complexity: O(N) +Time complexity: O(N) +*/ + +namespace Day1309 +{ + public class Exercise1 + { + public int SubarraySum(int[] nums, int k) + { + Dictionary dict = []; + int result = 0; + int total = 0; + + dict[0] = 1; + + foreach (int num in nums) + { + total += num; + int count = total - k; + + if (dict.ContainsKey(count)) + result += dict[count]; + + if (dict.ContainsKey(total)) + dict[total]++; + else + dict[total] = 1; + + } + + return result; + } + } +} \ No newline at end of file diff --git a/Topic7-HashTable/Day1309/Exercise2.cs b/Topic7-HashTable/Day1309/Exercise2.cs new file mode 100644 index 0000000..02fb32b --- /dev/null +++ b/Topic7-HashTable/Day1309/Exercise2.cs @@ -0,0 +1,40 @@ +//https://leetcode.com/problems/valid-anagram/ + +/* ++ Using array containing 26 lowercase English character + + First loop: to count the frequency of string s + + Second loop: to count the frequency of string t + + Third loop: To check to know that there is difference between 2 strings +Space complexity: O(26) +Time complexity: O(N) +*/ + +namespace Day1309 +{ + public class Exercise2 + { + public bool IsAnagram(string s, string t) + { + int[] charArr = new int[26]; + + int Length1 = s.Length; + int Length2 = t.Length; + + if (Length1 != Length2) return false; + + for (int i = 0; i < Length1; ++i) + ++charArr[s[i] - 'a']; + + for (int i = 0; i < Length2; ++i) + --charArr[t[i] - 'a']; + + for (int i = 0; i < 26; ++i) + { + if (charArr[i] != 0) + return false; + } + + return true; + } + } +} \ No newline at end of file