diff --git a/content/SoftwareEngineering/Leetcode/0001 - Contains Duplicated.md b/content/SoftwareEngineering/Leetcode/0001 - Contains Duplicated.md new file mode 100644 index 0000000000000..dfc341a68b214 --- /dev/null +++ b/content/SoftwareEngineering/Leetcode/0001 - Contains Duplicated.md @@ -0,0 +1,74 @@ +https://leetcode.com/problems/contains-duplicate/description/ + +#leetcode +#interview + +Given an integer array `nums`, return `true` if any value appears **at least twice** in the array, and return `false` if every element is distinct. + +**Example 1:** + +**Input:** nums = [1,2,3,1] + +**Output:** true + +**Explanation:** + +The element 1 occurs at the indices 0 and 3. + +**Example 2:** + +**Input:** nums = [1,2,3,4] + +**Output:** false + +**Explanation:** + +All elements are distinct. + +**Example 3:** + +**Input:** nums = [1,1,1,3,3,4,3,2,4,2] + +**Output:** true + +**Constraints:** + +- `1 <= nums.length <= 105` +- `-109 <= nums[i] <= 109` + + +Here's how you can solve the problem using Python. You can leverage the properties of sets to check for duplicates efficiently: + +```python +class Solution: + def containsDuplicate(self, nums: List[int]) -> bool: + # Create an empty set to store unique elements + seen = set() + + # Iterate through each number in the input list + for num in nums: + # If the number is already in the set, it means it's a duplicate + if num in seen: + return True + # Otherwise, add the number to the set + seen.add(num) + + # If no duplicates were found, return False + return False +``` + +### Explanation: +1. **Initialize a set**: `seen = set()`. Sets in Python do not allow duplicate values, which makes them useful for checking whether an element has already been seen. +2. **Iterate through `nums`**: For each number in the input list `nums`, check if it already exists in the `seen` set. +3. **Check for duplicates**: + - If `num` is already in `seen`, it means we've encountered a duplicate, so return `True`. + - If not, add `num` to the `seen` set. +4. If we iterate through the entire list without finding a duplicate, return `False`. + +### Time Complexity: +- The time complexity is O(n), where n is the number of elements in the list. Checking and inserting into a set both have an average time complexity of O(1). + +### Space Complexity: +- The space complexity is O(n) because, in the worst case, we might need to store all elements of the input list in the set. + +This solution efficiently checks for duplicates using sets and is well-suited for the given constraints. \ No newline at end of file diff --git a/content/SoftwareEngineering/Leetcode/0002 - Valid Anagram.md b/content/SoftwareEngineering/Leetcode/0002 - Valid Anagram.md new file mode 100644 index 0000000000000..c9e17bfc12ff0 --- /dev/null +++ b/content/SoftwareEngineering/Leetcode/0002 - Valid Anagram.md @@ -0,0 +1,178 @@ + +[242. Valid Anagram](https://leetcode.com/problems/valid-anagram/) + +Solved + +Easy + +Topics + +Companies + +Given two strings `s` and `t`, return `true` if `t` is an  + +anagram + + of `s`, and `false` otherwise. + +**Example 1:** + +**Input:** s = "anagram", t = "nagaram" + +**Output:** true + +**Example 2:** + +**Input:** s = "rat", t = "car" + +**Output:** false + +**Constraints:** + +- `1 <= s.length, t.length <= 5 * 104` +- `s` and `t` consist of lowercase English letters. + +**Follow up:** What if the inputs contain Unicode characters? How would you adapt your solution to such a case? + + + + + +Here's how you can solve the problem using Python by leveraging sorting or a frequency count approach: + +### Approach 1: Sorting +If two strings are anagrams, they should contain the same characters with the same frequency. By sorting the strings and comparing them, we can check if they are anagrams. + +```python +class Solution: + def isAnagram(self, s: str, t: str) -> bool: + # If the lengths of s and t are different, they can't be anagrams + if len(s) != len(t): + return False + + # Sort both strings and compare + return sorted(s) == sorted(t) +``` + +### Explanation: +1. **Check length**: If the lengths of `s` and `t` are different, return `False` immediately because they can't be anagrams. +2. **Sort and compare**: Sort both strings and check if they are equal. If they are, then `t` is an anagram of `s`. + +### Time Complexity: +- Sorting both strings takes O(n log n) time, where n is the length of the strings. + +### Space Complexity: +- Sorting requires additional space, but it depends on the language implementation. In general, the space complexity is O(1) if the sort is done in place, or O(n) if it creates a new sorted array. + +--- + +### Approach 2: Frequency Count +Instead of sorting, we can count the frequency of each character in both strings and compare the counts. + +```python +from collections import Counter + +class Solution: + def isAnagram(self, s: str, t: str) -> bool: + # If the lengths of s and t are different, they can't be anagrams + if len(s) != len(t): + return False + + # Count the frequency of characters in both strings and compare + return Counter(s) == Counter(t) +``` + +### Explanation: +1. **Check length**: If the lengths of `s` and `t` are different, return `False` immediately because they can't be anagrams. +2. **Frequency count**: Use the `Counter` from the `collections` module to count the frequency of each character in `s` and `t`. +3. **Compare counts**: If the two `Counter` objects are equal, `t` is an anagram of `s`. + +### Time Complexity: +- Counting the frequency of each character takes O(n) time. + +### Space Complexity: +- The space complexity is O(1) if the character set is fixed (e.g., 26 lowercase English letters), or O(n) if the character set can grow. + +### Follow-Up for Unicode Characters: +If the inputs contain Unicode characters, the same approach will work. The only change would be handling Unicode strings properly, which Python natively supports with its `str` and `Counter` functionalities. So, no modifications are required for the above code to work with Unicode characters. + + + + Here's the solution using a hashmap (dictionary) approach to check if two strings are anagrams: + +```python +class Solution: + def isAnagram(self, s: str, t: str) -> bool: + # If the lengths of s and t are different, they can't be anagrams + if len(s) != len(t): + return False + + # Create a dictionary to count characters in s + count_s = {} + + # Count the frequency of each character in s + for char in s: + if char in count_s: + count_s[char] += 1 + else: + count_s[char] = 1 + + # Subtract the frequency of each character in t + for char in t: + if char in count_s: + count_s[char] -= 1 + else: + # If a character in t is not in s, return False + return False + + # If all values in count_s are zero, it's an anagram + for count in count_s.values(): + if count != 0: + return False + + return True +``` + +### Explanation: +1. **Length check**: If `s` and `t` have different lengths, return `False` immediately. +2. **Count frequency for `s`**: Create a hashmap (`count_s`) where keys are characters in `s` and values are the frequency of each character. +3. **Adjust frequency for `t`**: For each character in `t`, decrease its count in `count_s`. + - If a character in `t` is not in `count_s`, return `False` (since it means `t` has a character not present in `s`). +4. **Check if all counts are zero**: After processing both strings, all the values in `count_s` should be zero. If not, it means the strings are not anagrams. + +### Time Complexity: +- O(n), where n is the length of the strings. Each character is processed twice (once for counting and once for adjusting). + +### Space Complexity: +- O(1), assuming a fixed character set like lowercase English letters (26 characters). If we consider all Unicode characters, it would be O(n) due to the possible large number of keys in the hashmap. + +### Why Use a Hashmap? +Using a hashmap (dictionary) is efficient for counting elements, as accessing and modifying dictionary entries is O(1). This approach avoids the overhead of sorting and works well even for larger inputs. + +Let me know if you'd like to see further optimizations or variations! + + + +Also good solution + + +```python + +class Solution: + def isAnagram(self, s: str, t: str) -> bool: + if len(s) != len(t): + return False + + countS, countT = {}, {} + + for i in range(len(s)): + countS[s[i]] = 1 + countS.get(s[i], 0) + countT[t[i]] = 1 + countT.get(t[i], 0) + return countS == countT + + + # easier solution + #return True if sorted(s) == sorted(t) else False +``` + +