Posted on

Maximum Score After Splitting a String

C++ Solution

class Solution {
public:
    int maxScore(string s) {
        int ones = count(s.begin(), s.end(), '1'); // Total 1's in the string
        int zeros = 0, result = 0; // Initialize count of zeros and result

        for (int i = 0; i < s.size() - 1; i++) { // Iterate but exclude the last split point
            if (s[i] == '1') 
                ones--; // Move '1' from right to left
            else 
                zeros++; // Increment count of '0's in the left part

            result = max(result, zeros + ones); // Update the maximum score
        }

        return result; // Return the best score
    }
};

Posted on

90% of CS graduates can’t figure this out

Someone important on X posted:

https://x.com/vikhyatk/status/1873033432705712304

i have a very simple question i ask during phone screens: print each level of a tree on a separate line. 90% of CS grad candidates just can’t do it. someone needs to investigate these universities.

half the replies are saying i’m trolling because no one asks questions this simple. the other half are saying it’s a retarded leetcode question, they never have to use trees irl, why is it even relevant because ChatGPT can do it etc.

Solution with Boost Library

#include <boost/property_tree/ptree.hpp>
#include <iostream>
#include <string>
#include <queue>
using namespace std;

void levelOrder(const boost::property_tree::ptree& tree) {
    std::queue<boost::property_tree::ptree> q;
    q.push(tree);

    while (!q.empty()) {
        int levelSize = q.size();
        while (levelSize > 0) {
            boost::property_tree::ptree current = q.front();
            q.pop();

            // Print the value at the current level
            auto val = current.get_value<std::string>("");
            if (val != "")
                std::cout << current.get_value<std::string>("")<<" ";

            // Add children nodes to the queue
            for (const auto& node : current) {
                q.push(node.second);
            }
            --levelSize;
        }
        std::cout << std::endl;  // Newline after printing one level
    }
}

int main() {
    // Create a Boost property tree
    boost::property_tree::ptree tree;

    // Insert elements to mimic a binary tree
    tree.put("root.value", "10");

    // Left child
    tree.put("root.left.value", "5");
    tree.put("root.left.left.value", "3");
    tree.put("root.left.right.value", "7");

    // Right child
    tree.put("root.right.value", "15");
    tree.put("root.right.right.value", "20");

    levelOrder(tree);

    return 0;
}

So I wanted to try out using Boost with CLion. What a nightmare. First the issue of using a flatpak install ruins everything when it comes to integrating with the system.

Second using a property tree was a bad idea. I should have went with a graph. Since the original post on X was talking about to solution with a graphic of a binary tree, I tried the property_tree in boost and I didn’t like the output of the tree still, nor the key value pair structure of it.

I will follow up later with a Breath First Search on a Undirected Graph from Boost library next time.

Posted on

Count Ways To Build Good Strings

Given the integers zeroonelow, and high, we can construct a string by starting with an empty string, and then at each step perform either of the following:

  • Append the character '0' zero times.
  • Append the character '1' one times.

This can be performed any number of times.

good string is a string constructed by the above process having a length between low and high (inclusive).

Return the number of different good strings that can be constructed satisfying these properties. Since the answer can be large, return it modulo 10<sup>9</sup> + 7.

Input: low = 3, high = 3, zero = 1, one = 1
Output: 8
Explanation: 
One possible valid good string is "011". 
It can be constructed as follows: "" -> "0" -> "01" -> "011". 
All binary strings from "000" to "111" are good strings in this example.

Input: low = 2, high = 3, zero = 1, one = 2
Output: 5
Explanation: The good strings are "00", "11", "000", "110", and "011".

Solution: fastest one is using tabulation dynamic programming technique.

    int countGoodStrings(int low, int high, int zero, int one) {
        int sum[100001];
        sum[0] = 1;
        for (int i = 1; i <= high; i++)
        {
            long long sumCur = 0;
            if (i >= zero)
                sumCur += sum[i-zero];
            if (i >= one)
                sumCur += sum[i-one];
            if (sumCur > 0x3000000000000000ll)
                sumCur %= 1000000007;
            sum[i] = sumCur % 1000000007;
        }

        long long sumTotal = 0;
        for (int i = low; i <= high; i++)
            sumTotal += sum[i];
        return sumTotal % 1000000007;
    }

Way slower approach is to use a map in your code for memoization, and a recursive DFS method.

class Solution {
public:
    int countGoodStrings(int low, int high, int zero, int one) {
        map<int, int> dp;
        long mod = pow(10,9) +7;    
        function<int(int)> dfs = [&](int length) -> int{
            
            if( length > high ) return 0;

            if(dp.find(length) != dp.end() )
                return dp[length];

            int count = ( length >= low) ? 1 : 0;
            count = (count + dfs(length + zero)) % mod;
            count = (count + dfs(length + one)) % mod;
            
            return dp[length] = count;
        };

        return dfs(0);    
    }
};

Posted on

Set Matrix Zeros

class Solution {
  public:
    void setMatrixZeroes(vector<vector<int>> &mat) {
        int n = mat.size();
        int m = mat[0].size();
    
        bool firstRowHasZero = false;
        bool firstColHasZero = false;
    
        // Check if the first row has any zero
        for (int j = 0; j < m; j++) {
            if (mat[0][j] == 0) {
                firstRowHasZero = true;
                break;
            }
        }
    
        // Check if the first column has any zero
        for (int i = 0; i < n; i++) {
            if (mat[i][0] == 0) {
                firstColHasZero = true;
                break;
            }
        }
    
        // Use the first row and column to mark zeros
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < m; j++) {
                if (mat[i][j] == 0) {
                    mat[i][0] = 0;
                    mat[0][j] = 0;
                }
            }
        }
    
        // Update the matrix based on the markers
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < m; j++) {
                if (mat[i][0] == 0 || mat[0][j] == 0) {
                    mat[i][j] = 0;
                }
            }
        }
    
        // Update the first row if needed
        if (firstRowHasZero) {
            for (int j = 0; j < m; j++) {
                mat[0][j] = 0;
            }
        }
    
        // Update the first column if needed
        if (firstColHasZero) {
            for (int i = 0; i < n; i++) {
                mat[i][0] = 0;
            }
        }
        
    }
};

The idea here is using the first row and column as a Dynamic Programming table to mark which rows and columns need to be zeroed out.
That being done, then first column and row itself is updated at the end.

Posted on

Zigzag string conversion solution in C++

The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this

Input: s = "PAYPALISHIRING", numRows = 3 Output: "PAHNAPLSIIGYIR"
P   A   H   N
A P L S I I G
Y   I   R

Input: s = "PAYPALISHIRING", numRows = 4 Output: "PINALSIGYAHRPI"
P     I    N
A   L S  I G
Y A   H R
P     I

Solution

#include <iostream>
#include <string>
using namespace std;

class Solution {
public:
    string convert(string s, int numRows) {
        int n = s.size();
        if (n == 1 || numRows < 2 || n <= numRows) return s;
        
        string ans;
        
        for (int i = 0; i < numRows; i++) {
            int j = i;
            ans.push_back(s[i]); // First character of the row
            int down = 2 * (numRows - 1 - i); // Downward step size
            int up = 2 * i; // Upward step size
            
            if (up == 0 && down == 0) return s; // If no movement, just return the string
            
            while (j < n) {
                j += down;
                if (j < n && down > 0) ans.push_back(s[j]);
                
                j += up;
                if (j < n && up > 0) ans.push_back(s[j]);
            }
        }
        
        return ans;
    }
};

int main() {
    Solution solution;
    string s = "PAYPALISHIRING"; // Example input
    int numRows = 3; // Example row count
    
    string result = solution.convert(s, numRows);
    cout << "Zigzag Conversion: " << result << endl; // Output the result
    return 0;
}
Posted on

Search Sorted Matrix Solution in C++

The idea here is to implement binary search after discovering the correct row.


#include <bits/stdc++.h>
using namespace std;



class Solution {
  public:
  
  
    // Function to search a given number in row-column sorted matrix.
    bool searchMatrix(vector<vector<int>> &mat, int x) {
        // code here
        vector<int>*row = nullptr;
        int rows = mat.size();
        int cols = mat[0].size();
        
        for( int i = 0; i < rows; i++ ){
            if( mat[i][0] <= x && mat[i][cols-1] >= x ){
                row = &(mat[i]);
                break;
            }
        }
        
        if( row == nullptr ) return false;
        
        auto binarySearch = [row, x]( int low, int high ) -> bool{
            
            while( low <= high ){
                int mid = low + (high-low)/2;
            
                if( (*row)[mid] == x ){
                    return true;
                }else if((*row)[mid] < x ){
                    low =  mid + 1;
                } else {
                    high = mid - 1;
                }
                
            }
            
            return false;
            
        };   
        
        return binarySearch(0, cols -1 );
    }
};

Posted on

LeetCode 543 Diameter of a Binary Tree in C++

Given the root of a binary tree, return the length of the diameter of the tree.

The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root.

The length of a path between two nodes is represented by the number of edges between them.

Example 1:
Input: root = [1,2,3,4,5] Output: 3
Explanation: 3 is the length of the path [4,2,1,3] or [5,2,1,3].


Example 2:
Input: root = [1,2] Output: 1

Constraints:

-100 <= Node.val <= 100

The number of nodes in the tree is in the range [1, 104].

Solution in C++ with a test case:


#include <iostream>
#include <algorithm>
using namespace std;

// Definition for a binary tree node.
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};

class Solution {
public:
    int result;
    int dfs(TreeNode* root) {
        if (root == nullptr) return 0;
        int left = dfs(root->left);
        int right = dfs(root->right);
        result = max(result, left + right);
        return max(left, right) + 1;
    }

    int diameterOfBinaryTree(TreeNode* root) {
        result = 0;
        dfs(root);
        return result;
    }
};

// Helper function to create a tree
TreeNode* createTree() {
    /*
        Example tree:
                1
               / \
              2   3
             / \
            4   5
    */
    TreeNode* root = new TreeNode(1);
    root->left = new TreeNode(2);
    root->right = new TreeNode(3);
    root->left->left = new TreeNode(4);
    root->left->right = new TreeNode(5);
    return root;
}

int main() {
    // Create a sample binary tree
    TreeNode* root = createTree();

    // Create a Solution object
    Solution solution;

    // Call the diameterOfBinaryTree function
    int diameter = solution.diameterOfBinaryTree(root);

    // Output the result
    cout << "Diameter of the binary tree: " << diameter << endl;

    // Clean up memory (optional but good practice)
    delete root->left->left;
    delete root->left->right;
    delete root->left;
    delete root->right;
    delete root;

    return 0;
}
Posted on

401. Binary Watch

A binary watch has 4 LEDs on the top to represent the hours (0-11), and 6 LEDs on the bottom to represent the minutes (0-59). Each LED represents a zero or one, with the least significant bit on the right.

  • For example, the below binary watch reads "4:51".

Given an integer turnedOn which represents the number of LEDs that are currently on (ignoring the PM), return all possible times the watch could represent. You may return the answer in any order.

The hour must not contain a leading zero.

  • For example, "01:00" is not valid. It should be "1:00".

The minute must consist of two digits and may contain a leading zero.

  • For example, "10:2" is not valid. It should be "10:02".

Example 1:

Input: turnedOn = 1
Output: ["0:01","0:02","0:04","0:08","0:16","0:32","1:00","2:00","4:00","8:00"]

Example 2:

Input: turnedOn = 9
Output: []

Solution

import java.util.ArrayList;
import java.util.List;

class Solution {
    public List<String> readBinaryWatch(int turnedOn) {
        List<String> result = new ArrayList<>();

        // Iterate over possible hours (0 to 11)
        for (int hour = 0; hour < 12; hour++) {
            // Iterate over possible minutes (0 to 59)
            for (int minute = 0; minute < 60; minute++) {
                // Count the number of bits turned on
                int bitsOn = Integer.bitCount(hour) + Integer.bitCount(minute);
                
                // If the total bits on matches the turnedOn count
                if (bitsOn == turnedOn) {
                    // Format the time as "H:MM"
                    result.add(String.format("%d:%02d", hour, minute));
                }
            }
        }
        return result;
    }
}
Posted on

Letter Combinations of a phone number

Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent. Return the answer in any order.

A mapping of digits to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.

Example 1:

Input: digits = "23"
Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"]

Example 2:

Input: digits = ""
Output: []

Example 3:

Input: digits = "2"
Output: ["a","b","c"]

Java Solution

class Solution {
     public List<String> letterCombinations(String digits) {
        if (digits == null || digits.length() == 0) {
            return new ArrayList<>();
        }
        Map<Character, String> digitToLetters = new HashMap<>();
        digitToLetters.put('2', "abc");
        digitToLetters.put('3', "def");
        digitToLetters.put('4', "ghi");
        digitToLetters.put('5', "jkl");
        digitToLetters.put('6', "mno");
        digitToLetters.put('7', "pqrs");
        digitToLetters.put('8', "tuv");
        digitToLetters.put('9', "wxyz");

        List<String> result = new ArrayList<>();
        backtrack(digits, 0, new StringBuilder(), result, digitToLetters);
        return result;
    }

    private void backtrack(String digits, int index, StringBuilder path, List<String> result, Map<Character, String> digitToLetters) {
        if (index == digits.length()) {
            result.add(path.toString());
            return;
        }

        char digit = digits.charAt(index);
        String letters = digitToLetters.get(digit);
        for (char letter : letters.toCharArray()) {
            path.append(letter);
            backtrack(digits, index + 1, path, result, digitToLetters);
            path.deleteCharAt(path.length() - 1);
        }
    }
}

C++ Solution

//
// Created by robert on 12/20/24.
//
#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;
void backtrack(string & digits, const int index, string & current, vector<string> & result, const unordered_map<char,string> & map) {
if (digits.length() == index) {
result.push_back(current);
return;
}
char digit = digits[index];
string letters = map.find(digit)->second;
for( char letter : letters ) {
current.push_back(letter);
backtrack( digits, index+1, current, result, map );
current.pop_back();
}

}
vector<string> letterCombinations(string digits) {
vector<string> result;
string current;

if (digits.empty()) return result;

unordered_map<char, string> map;

map.insert(make_pair('2', "abc"));
map.insert(make_pair('3', "def"));
map.insert(make_pair('4', "ghi"));
map.insert(make_pair('5', "jkl"));
map.insert(make_pair('6', "mno"));
map.insert(make_pair('7', "pqrs"));
map.insert(make_pair('8', "tuv"));
map.insert(make_pair('9', "wxyz"));


backtrack(digits, 0, current, result, map);
return result;

}

int main(){
vector<string> result = letterCombinations("23");
for (const auto & i : result) {
cout << i << endl;
}
}
Posted on

LeetCode 20 Valid Parentheses in Typescript

The mental challenge one might experience here is that JavaScript doesn’t have abstract data structures like stacks and queues built into the language. Implementations of those structures use an array underneath. So solving this problem is just as easy in TypeScript as it is in C++ with a stack. The problem is defined as:

Given a string s containing just the characters '('')''{''}''[' and ']', determine if the input string is valid.

An input string is valid if:

  1. Open brackets must be closed by the same type of brackets.
  2. Open brackets must be closed in the correct order.
  3. Every close bracket has a corresponding open bracket of the same type.

Example 1: Input: s = “()” Output: true

Example 2: Input: s = “()[]{}” Output: true

Example 3: Input: s = “(]” Output: false

Example 4: Input: s = “([])” Output: true

Solution:

function isValid(s: string): boolean {
    
    const st:string[] = [];
    for( const c of s){
        
        if( c === '(' || c === '[' || c === '{'){
            st.push(c);
        } else {
            const last =  st[st.length - 1];
            if( c === '(' && last === ')') st.pop();
            else if( c === '[' && last === ']') st.pop();
            else if( c === '{' && last === '}') st.pop();
            else st.push(c);
        }

        
    }
    
    return st.length === 0;
};