having-fun-tickling-algorithms

Table of contents

7. Reverse Integer

class Solution {
    public int reverse(int x) {
        long result = 0;
        while (x != 0){
            int remainder = x%10; //get the last digit
            result = result*10 + remainder;
            if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) return 0;
            x = x/10;
        }
        return (int) result;

    }
}

234. Palindrome Linked List

36. Valid Sudoku

Approach 1: Use 1 hashset

class Solution {
    public boolean isValidSudoku(char[][] board) {
        Set seen = new HashSet();
        for(int i = 0; i <9; i ++){
            for(int j = 0; j <9; j++){
                if (board[i][j] != '.'){
                    if (!seen.add(board[i][j] + "in row" + i) ||
                        !seen.add(board[i][j] + "in col" + j) ||
                        !seen.add(board[i][j] + "in grid" + i/3 + "-" + j/3)){
                        return false;
                    }
                }
            }
        }
        return true;
    }
}

1300. Sum of Mutated Array Closest to Target

Low ends up becoming is the minimum value that satisfies sum(arr,mid) >= target.


692. Top K Frequent Words

Approach 1: Priority Queue Heap

What structure is perfect for maintaining an order as we are adding and removing elements? priority queue!

Min heap, max heap
["i","love","leetcode","i","love","coding"]
i = 2
love = 2
leetcode = 1
coding = 1
---> order by alphabetic orders:
Priority Queue: i love

---> only k elements, removing the element with greater alphatic order or less frequency
O(n log K): Insertion has worst case of O(log n)
O(n) * O(logK)
Loop through the word   insertion
class Solution {
    public List<String> topKFrequent(String[] words, int k) {
        HashMap<String, Integer> map = new HashMap();
        for(int i = 0; i < words.length; i ++){
            map.put(words[i], map.getOrDefault(words[i], 0) + 1);
        }

        PriorityQueue<String> pq = new PriorityQueue(new Comparator<String>(){
            @Override
            public int compare(String word1, String word2){
                int frequency1 = map.get(word1);
                int frequency2 = map.get(word2);
                if(frequency1 == frequency2) return word2.compareTo(word1);
                else return frequency1 - frequency2;
            }
        });

        for(Map.Entry<String, Integer> entry : map.entrySet()){
            pq.add(entry.getKey());
            if(pq.size() > k) pq.poll();
        }
        List<String> output = new ArrayList<>();
        while(!pq.isEmpty() ){
            output.add(pq.poll());
        }
        Collections.reverse(output);
        return output;

    }
}

1328. Break a Palindrome

Approach 1: Greedy Algo

replace a non 'a' character to 'a'.
public String breakPalindrome(String palindrome) {
        int len = palindrome.length();
        StringBuilder ans = new StringBuilder(palindrome);
        // no way to replace a character to make it not a palindrome
        if(len == 0 || len == 1) return "";
        for(int i = 0; i < len/2; i++){
            if(palindrome.charAt(i) != 'a'){
               ans.setCharAt(i, 'a');
               return ans.toString();
            }
        }
        ans.setCharAt(len-1, 'b');
        return ans.toString();
    }

62. Unique Paths

Approach 1: Dynamic Programming

dp[i][j] = dp[i-1][j] + dp[i][j-1];

 public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        for(int i = 0; i < m; i ++){
            for(int j = 0; j < n; j++){
                if(i == 0 || j == 0){
                    dp[i][j] = 1;
                }else{
                    dp[i][j] = dp[i-1][j] + dp[i][j-1];
                }
            }
        }
        return dp[m-1][n-1];
    }

Approach 2: Memoization

class Solution {
    private Map<String, Integer> map = new HashMap<String, Integer>();
    public int uniquePaths(int m, int n) {
        //base case
        if (m == 1 || n == 1) return 1;
        // check if we have already calculated unique paths for cell(m, n)
        String cell = new String(m + "," + n);
        // if yes, then get its value from our memoization table
        if (map.containsKey(cell)) return map.get(cell);
        // else, explore the down move
        int downMove = uniquePaths(m-1, n);
        // explore the right move
        int rightMove = uniquePaths(m, n-1);

        //put the value obtained for unique paths from cell(m,n)
        map.put(cell, downMove + rightMove);
        return downMove + rightMove;
    }
}

91. Decode Ways

Approach 1: DP

determine how many ways, use all the subproblems up to solve the nth problem

        int ans = 0;
        int[] dp = new int[s.length() + 1];
        dp[0] = 1;
        dp[1] = s.charAt(0) == '0'? 0 : 1;
        for(int i = 2; i <= s.length(); i ++){
            int oneDigit = Integer.valueOf(s.substring(i-1, i));
            int twoDigit = Integer.valueOf(s.substring(i-2,i));
            if (oneDigit > 0 && oneDigit < 10){
                dp[i] += dp[i-1];
            }
            if(twoDigit >= 10 && twoDigit <= 26){
                dp[i] += dp[i-2];
            }
        }
        return dp[s.length()];

49. Group Anagrams

Approach 1: HashTable

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        List<List<String>> list = new ArrayList();
        if (strs.length == 0) return list;
        //key: sorted string
        //value: the list of anagram strings
        HashMap<String, List<String>> map = new HashMap();
        for(String curr: strs){
            char[] c = curr.toCharArray();
            Arrays.sort(c);
            String sorted = new String(c);
            if (!map.containsKey(sorted)){
                map.put(sorted, new ArrayList());
            }
            //add the current word to the arraylist
            map.get(sorted).add(curr);
        }
        list.addAll(map.values());
        return list;
    }
}

Approach 2: Frequency array

public List<List<String>> groupAnagrams(String[] strs) {
        if(strs == null || strs.length == 0) return Collections.emptyList();
        Map<String, List<String>> map = new HashMap<>();
        for(String s: strs){
            char[] frequencyArr = new char[26];
            for(int i = 0;i<s.length();i++){
                frequencyArr[s.charAt(i) - 'a']++;
            }
            String key = new String(frequencyArr);
            List<String> tempList = map.getOrDefault(key, new LinkedList<String>());
            tempList.add(s);
            map.put(key,tempList);
        }
        return new LinkedList<>(map.values());
    }

##

Approach 1:


##

Approach 1:


##

Approach 1:


##

Approach 1:


##

Approach 1:


##

Approach 1:


##

Approach 1:


##

Approach 1: