A month ago, my company laid off 40% of its employees — approximately 4,000 people. The team that I was on was reduced from about 18 engineers to 3. My manager was also let go. Entire teams were decimated or eliminated. It was a sad and frustrating time. I saw amazing and talented engineers let go. The layoff was illogical and capricious and it did not take into consideration the performance of the engineers.
Even though I did not get laid off, the writing is on the wall and I need to be always ready to get laid off or fired. An ex-colleague of mine posted on LinkedIn that he was interviewing for a software engineering position once, and during the interview the interviewing manager said that he expected all his reports to interview at least once a year to understand their value and to always be ready. I think that it is good advice.
My goal is to practice Leetcode type questions 2 to 3 times a week so I can prepare for interviews and to also improve my coding skills. I am using neetcode.io as a study guide. Neetcode is a great resource, and it provides sample questions and explanations to problems.
I am working on the Blind 75 problem set in Neetcode. It is a collection of problems commonly found in interviews. I am starting with the Arrays & Hashing section.
My first problem is Leetcode 217 – Contains duplicates.
Given an integer array
nums, returntrueif any value appears at least twice in the array, and returnfalseif every element is distinct.
This is an easy problem and my solution is below.
class Solution {
fun containsDuplicate(nums: IntArray): Boolean {
val numbersFoundSet = mutableSetOf<Int>()
nums.forEach {
if(numbersFoundSet.contains(it)){
return true
}
else {
numbersFoundSet.add(it)
}
}
return false
}
}
The way I solved this is by using a set to keep track of which numbers are found. If a number is already found, I immediately return true since the number appears twice. If I iterate through all the numbers then I return false since all numbers are distinct.
My second problem is Leetcode 242 – Valid anagram.
Given two strings
sandt, returntrueiftis an anagram ofs, andfalseotherwise.
This is a little more interesting. Here is my first approach where I create a map to track how many times a character is used. I read the string s and populate the map. I then read the string t and check if the map contains the character and then decrement the count or remove the character from the map if the count is 0. At the end, I expect the map to be empty.
class Solution {
fun isAnagram(s: String, t: String): Boolean {
val characterCountMap = mutableMapOf<Char, Int>()
s.forEach{
val count = characterCountMap.getOrDefault(it, 0)
if(count == 0) {
characterCountMap[it] = 1
}else{
characterCountMap[it] = count + 1
}
}
t.forEach {
val count = characterCountMap[it]
if(count == null) {
return false
}else{
val newCount = count - 1
if(newCount == 0){
characterCountMap.remove(it)
}else{
characterCountMap[it] = newCount
}
}
}
return characterCountMap.isEmpty()
}
}
This solution works but I was curious to see what other ways it could be solved. I asked Claude how it would solve it and this is what it came up with:
fun isAnagram(s: String, t: String): Boolean {
if (s.length != t.length) return false
val counts = IntArray(26)
for (i in s.indices) {
counts[s[i] - 'a']++
counts[t[i] - 'a']--
}
return counts.all { it == 0 }
}
The Claude solution is cool. It uses a fixed IntArray of size 26 so the memory is constant and it uses the character integer value as the index. It then increments for all characters in string s and decrements for all characters in string t. At the end, all the counts should be 0.
With this practice session, I practiced writing code in Kotlin without any IDE support and also got a refresher on working with characters.