diff --git a/.github/lc_chart.png b/.github/lc_chart.png index 2ea25a4..e857abe 100644 Binary files a/.github/lc_chart.png and b/.github/lc_chart.png differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eae414f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*__pycache__ +**/revision.txt \ No newline at end of file diff --git a/README.md b/README.md index 9929ab5..fc6e1f7 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,10 @@ The following diagram illustrates the action flow of using these [scripts](scrip |**66**|🟩 Easy|⚙️|[Plus One](https://lcid.cc/66)|| |**73**|🟨 Medium|⚙️|[Set Matrix Zeroes](https://lcid.cc/73)|| |**77**|🟨 Medium|⚙️|[Combinations](https://lcid.cc/77)|| +|**125**|🟩 Easy|⚙️|[Valid Palindrome](https://lcid.cc/125)|| |**128**|🟨 Medium|⚙️|[Longest Consecutive Sequence](https://lcid.cc/128)|| |**136**|🟩 Easy|⚙️|[Single Number](https://lcid.cc/136)|| -|**151**|🟨 Medium|⚙️|[Reverse Words In A String](https://lcid.cc/151)|| +|**151**|🟨 Medium|⚙️|[Reverse Words In A String](https://lcid.cc/151)| | |**175**|🟩 Easy|🛢️|[Combine Two Tables](https://lcid.cc/175)| | |**176**|🟨 Medium|🛢️|[Second Highest Salary](https://lcid.cc/176)|| |**178**|🟨 Medium|🛢️|[Rank Scores](https://lcid.cc/178)|| @@ -49,6 +50,7 @@ The following diagram illustrates the action flow of using these [scripts](scrip |**230**|🟨 Medium|⚙️|[Kth Smallest Element In A Bst](https://lcid.cc/230)|| |**238**|🟨 Medium|⚙️|[Product Of Array Except Self](https://lcid.cc/238)| | |**242**|🟩 Easy|⚙️|[Valid Anagram](https://lcid.cc/242)| | +|**268**|🟩 Easy|⚙️|[Missing Number](https://lcid.cc/268)|| |**271**|🟨 Medium|⚙️|[Encode And Decode Strings](https://lcid.cc/271)|| |**283**|🟩 Easy|⚙️|[Move Zeroes](https://lcid.cc/283)|| |**334**|🟨 Medium|⚙️|[Increasing Triplet Subsequence](https://lcid.cc/334)|| @@ -146,6 +148,7 @@ The following diagram illustrates the action flow of using these [scripts](scrip |**1672**|🟩 Easy|⚙️|[Richest Customer Wealth](https://lcid.cc/1672)|| |**1679**|🟨 Medium|⚙️|[Max Number Of K-sum Pairs](https://lcid.cc/1679)|| |**1683**|🟩 Easy|🛢️|[Invalid Tweets](https://lcid.cc/1683)|| +|**1684**|🟩 Easy|⚙️|[Count The Number Of Consistent Strings](https://lcid.cc/1684)|| |**1693**|🟩 Easy|🛢️|[Daily Leads And Partners](https://lcid.cc/1693)|| |**1700**|🟩 Easy|⚙️|[Number Of Students Unable To Eat Lunch](https://lcid.cc/1700)|| |**1720**|🟩 Easy|⚙️|[Decode Xored Array](https://lcid.cc/1720)|| diff --git a/java/lce_p0125_valid_palindrome.java b/java/lce_p0125_valid_palindrome.java new file mode 100644 index 0000000..b7fe6de --- /dev/null +++ b/java/lce_p0125_valid_palindrome.java @@ -0,0 +1,119 @@ +/* + LCE 125. Valid Palindrome + + A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. + Alphanumeric characters include letters and numbers. + + Given a string s, return true if it is a palindrome, or false otherwise. + + Constraints: + - 1 <= s.length <= 2 * 10^5 + - s consists only of printable ASCII characters. + + Topics: Two Pointers, String +*/ + +class Solution { + + // Time Complexity: O(n) - 1 ms -> 100.00% + // Space Complexity: O(n) - 43.11 MB -> 69.00% + public boolean isPalindrome(String s) { + + int startPtr = 0; + int endPtr = s.length() - 1; + + while (startPtr < endPtr) { + + char startChar = s.charAt(startPtr); + char endChar = s.charAt(endPtr); + + if (startChar >= 'A' && startChar <= 'Z') startChar = (char) (startChar - 'A' + 'a'); + if (endChar >= 'A' && endChar <= 'Z') endChar = (char) (endChar - 'A' + 'a'); + + if (!((startChar >= 'a' && startChar <= 'z') || (startChar >= '0' && startChar <= '9'))) { + startPtr++; + continue; + } + else if (!((endChar >= 'a' && endChar <= 'z') || (endChar >= '0' && endChar <= '9'))) { + endPtr--; + continue; + } + else { + if (startChar != endChar) { + return false; + } + + startPtr++; + endPtr--; + } + } + + return true; + } + + // Time Complexity: O(n) - 4 ms -> 55.36% + // Space Complexity: O(n) - 43.68 MB -> 52.39% + public boolean isPalindrome2(String s) { + + // as per first requirement + s = getCleanedString(s); + + int n = s.length(); + + // case 1: string length 0 ("") or 1 ("a") + if (n <= 1) { + return true; + } + + // case 2: string length 2 ("ab" or "aa") + if (n == 2) { + return s.charAt(0) == s.charAt(1); + } + + // case 3: string length >= 3 + int startPtr = 0; + int endPtr = n - 1; + + while (startPtr < endPtr) { + + char startChar = s.charAt(startPtr); + char endChar = s.charAt(endPtr); + + if (startChar != endChar) { + return false; + } + + startPtr++; + endPtr--; + } + + return true; + } + + private String getCleanedString(String s) { + + return s.replaceAll("[^a-zA-Z0-9]+", "").toLowerCase(); + } + + private String getCleanedStringII(String s) { + + StringBuilder sb = new StringBuilder(); + + for (char ch : s.toCharArray()) { + if (Character.isDigit(ch)) { + sb.append(ch); + } + if (Character.isLetter(ch)) { + sb.append(Character.toLowerCase(ch)); + } + } + + return sb.toString(); + } +} + +/* + methods: + 1. single pass - first skip ch and advance ptrs if it is not alphanumeric for ch at startPtr / endPtr, if both are OK then compare them + 2. double pass - 1st pass - clean the string as per requirements, 2nd pass - check ch at startPtr / endPtr +*/ \ No newline at end of file diff --git a/java/lce_p0242_valid_anagram.java b/java/lce_p0242_valid_anagram.java index 676918c..c6351ec 100644 --- a/java/lce_p0242_valid_anagram.java +++ b/java/lce_p0242_valid_anagram.java @@ -74,7 +74,7 @@ public boolean isAnagramAlt2(String s, String t) { char[] charT = t.toCharArray(); Arrays.sort(charS); Arrays.sort(charT); - + return Arrays.equals(charS, charT); } } diff --git a/java/lce_p0268_missing_number.java b/java/lce_p0268_missing_number.java new file mode 100644 index 0000000..9106e58 --- /dev/null +++ b/java/lce_p0268_missing_number.java @@ -0,0 +1,46 @@ +/* + LCE 268. Missing Number + + Given an array nums containing n distinct numbers in the range [0, n], return the only number in the range that is missing from the array. + + Constraints: + - n == nums.length + - 1 <= n <= 10^4 + - 0 <= nums[i] <= n + - All the numbers of nums are unique. + + Topics: Array, Hash Table, Math, Binary Search, Bit Manipulation, Sorting +*/ + +class Solution { + + /* + - XOR is commutative: A ^ B = B ^ A + - XOR is associative: (A ^ B) ^ C = A ^ (B ^ C) + - XORing something twice removes it: A ^ A = 0 + - XORing with zero does nothing: A ^ 0 = A + */ + + public int missingNumber(int[] nums) { + + int n = nums.length; + + int firstSumXOR = 0; + int secondSumXOR = 0; + + // e.g. all in [0, n] => [0, 1, 2, 3] + for (int i = 0; i <= n; i++) { + firstSumXOR ^= i; + } + + // e.g. nums => [3, 0, 1] + for (int num : nums) { + secondSumXOR ^= num; + } + + return firstSumXOR ^ secondSumXOR; // 2 + } +} + +// Time Complexity: O(n) - 0 ms -> 100.00% +// Space Complexity: O(1) - 45.26 MB -> 40.66% \ No newline at end of file diff --git a/java/lce_p1684_count_the_number_of_consistent_strings.java b/java/lce_p1684_count_the_number_of_consistent_strings.java new file mode 100644 index 0000000..1de06d3 --- /dev/null +++ b/java/lce_p1684_count_the_number_of_consistent_strings.java @@ -0,0 +1,42 @@ +/* + LCE 1684. Count the Number of Consistent Strings + + You are given a string 'allowed' consisting of distinct characters and an array of strings 'words'. + A string is consistent if all characters in the string appear in the string 'allowed'. + + Return the number of consistent strings in the array 'words'. + + Constraints: + - n == nums.length + - 1 <= n <= 10^4 + - 0 <= nums[i] <= n + - All the numbers of nums are unique. + + Topics: Array, Hash Table, String, Bit Manipulation, Counting +*/ + +class Solution { + public int countConsistentStrings(String allowed, String[] words) { + + boolean[] allowedChars = new boolean[26]; + for (char ch : allowed.toCharArray()) { + allowedChars[ch - 'a'] = true; + } + + int count = words.length; + for (String word : words) { + + for (char ch : word.toCharArray()) { + if (!allowedChars[ch - 'a']) { + count--; + break; + } + } + } + + return count; + } +} + +// Time Complexity: O(n^2) - 6 ms -> 82.59% +// Space Complexity: O(1) - 45.27 MB -> 65.85% \ No newline at end of file diff --git a/java/lcm_p0049_group_anagrams.java b/java/lcm_p0049_group_anagrams.java index 237c1da..1ee26fd 100644 --- a/java/lcm_p0049_group_anagrams.java +++ b/java/lcm_p0049_group_anagrams.java @@ -4,7 +4,7 @@ Given an array of strings strs, group the anagrams together. You can return the answer in any order. Constraints: - - 1 <= strs.length <= 104 + - 1 <= strs.length <= 10^4 - 0 <= strs[i].length <= 100 - strs[i] consists of lowercase English letters. diff --git a/java/lcm_p0128_longest_consecutive_sequence.java b/java/lcm_p0128_longest_consecutive_sequence.java index 2b31cd8..75c56bc 100644 --- a/java/lcm_p0128_longest_consecutive_sequence.java +++ b/java/lcm_p0128_longest_consecutive_sequence.java @@ -30,7 +30,7 @@ public int longestConsecutive(int[] nums) { Set set = new HashSet<>(); for (int num : nums) set.add(num); - + for (int num : nums) { // process only starting numbers @@ -44,10 +44,10 @@ public int longestConsecutive(int[] nums) { maxLength = Math.max(currLength, maxLength); } } - + return maxLength; } - + // Time Complexity: O(n log n) - 16 ms -> 91.59% // Space Complexity: O(1) - 56.8 MB -> 81.76% public int longestConsecutiveAlt(int[] nums) { diff --git a/java/lcm_p0151_reverse_words_in_a_string.java b/java/lcm_p0151_reverse_words_in_a_string.java new file mode 100644 index 0000000..469e193 --- /dev/null +++ b/java/lcm_p0151_reverse_words_in_a_string.java @@ -0,0 +1,48 @@ +/* + LCM 151. Reverse Words in a String + + Given an input string s, reverse the order of the words. + + A word is defined as a sequence of non-space characters. + The words in s will be separated by at least one space. + + Return a string of the words in reverse order concatenated by a single space. + + Note that s may contain leading or trailing spaces or multiple spaces between two words. + The returned string should only have a single space separating the words. Do not include any extra spaces. + + Constraints: + - 1 <= s.length <= 10^4 + - s contains English letters (upper-case and lower-case), digits, and spaces ' '. + - There is at least one word in s. + + Topics: Two Pointers, String +*/ + +class Solution { + public String reverseWords(String s) { + + // note: "\\s+" matches sequence of one or more whitespace characters. + String[] words = s.trim().split("\\s+"); + + reverseArray(words); + + return String.join(" ", words); + } + + // alternative: use Collections.reverse(List) instead. + private void reverseArray(String[] words) { + + int n = words.length; + + for (int i = 0; i < n / 2; i++) { + String temp = words[i]; + words[i] = words[n - i - 1]; + words[n - i - 1] = temp; + } + } +} + +// Time Complexity: O(L) - 8 ms -> 39.40% +// Space Complexity: O(L) - 42.65 MB -> 94.35% +// L => length of string s \ No newline at end of file