Posted on

Non Repeating Character

Difficulty: Easy
Accuracy: 40.43%
Submissions: 262K+Points: 2

Given a string s consisting of lowercase Latin Letters. Return the first non-repeating character in s. If there is no non-repeating character, return ‘$’.
Note: When you return ‘$’ driver code will output -1.

Examples:

Input: s = "geeksforgeeks"
Output: 'f'
Explanation: In the given string, 'f' is the first character in the string which does not repeat.
Input: s = "racecar"
Output: 'e'
Explanation: In the given string, 'e' is the only character in the string which does not repeat.
Input: s = "aabbccc"
Output: -1
Explanation: All the characters in the given string are repeating.

Constraints:
1 <= s.size() <= 105

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

char firstNonRepeatingChar(const string& s) {
    // Step 1: Count frequencies of each character
    unordered_map<char, int> charCount;
    for (char c : s) {
        charCount[c]++;
    }

    // Step 2: Find the first non-repeating character
    for (char c : s) {
        if (charCount[c] == 1) {
            return c; // First non-repeating character found
        }
    }

    // Step 3: No non-repeating character
    return '$';
}

int main() {
    string s = "geeksforgeeks";
    char result = firstNonRepeatingChar(s);

    if (result == '$') {
        cout << -1 << endl; // Follow the note: '$' indicates no non-repeating character
    } else {
        cout << result << endl;
    }

    return 0;
}

To solve the problem of finding the first non-repeating character in a string, we can use an efficient approach by incorporating a hashmap (or an equivalent data structure) to count the frequency of characters in the string. Here’s the step-by-step solution:

Steps to Solve:

  1. Count Character Frequencies:
    • Traverse the string and count the occurrences of each character.
    • Store the counts in a dictionary (or a hashmap).
  2. Find the First Non-Repeating Character:
    • Traverse the string again, and for each character, check its frequency in the hashmap.
    • The first character with a frequency of 1 is the first non-repeating character.
  3. Return the Result:
    • If no character has a frequency of 1, return $.

Algorithm Complexity:

  1. Time Complexity:
    • Counting frequencies: O(n) (single traversal for the frequency hashmap).
    • Traversing again to find the first non-repeating character: O(n).
    • Total: O(n).
  2. Space Complexity:
    • Storing frequencies in a hashmap requires O(26) (in the worst case, since there are only 26 lowercase Latin letters). This is O(1) space.
Posted on

Maximum difference between pair in a matrix

https://www.geeksforgeeks.org/problems/maximum-difference-between-pair-in-a-matrix/

Difficulty: Hard
Accuracy: 49.36%
Submissions: 2K+Points: 8

Given an n x n matrix, mat[n][n] of integers. The task is to find the maximum value of mat(c, d)- mat(a, b) over all choices of indexes such that both c > a and d > b.

Example 1:

Input: mat[N][N] = {{ 1, 2, -1, -4, -20 },
             { -8, -3, 4, 2, 1 }, 
             { 3, 8, 6, 1, 3 },
             { -4, -1, 1, 7, -6 },
             { 0, -4, 10, -5, 1 }};
Output: 18
Explanation: The maximum value is 18 as mat[4][2] - mat[1][0] = 18 has maximum difference.

Your Task:  
You don’t need to read input or print anything. Your task is to complete the function findMaxValue() which takes a matrix mat and returns an integer as output.

Expected Time Complexity: O(n2)
Expected Auxiliary Space: O(n2)

Constraints:
1 <= n<= 103
-103<= mat[i][j] <=103

Approach:

  1. Observation: If we fix (c, d) as the bottom-right element of a submatrix, then for any fixed (a, b) where a < c and b < d, the maximum value of mat(c, d) - mat(a, b) depends on the smallest value seen in all submatrices containing (c, d).
  2. Dynamic Programming Strategy:
    • Precompute the max_matrix so that max_matrix[i][j] contains the maximum element in the submatrix starting from (i, j) to the bottom-right corner of the mat.
    • Iterate over all possible (a, b) positions and calculate the maximum difference using max_matrix.
    • Update the result during each iteration.
  3. Algorithm:
    • Start from the bottom right of the matrix and move to the top left.
    • Precompute the max_matrix while iterating.
    • Calculate the result using:
#include <iostream>
#include <vector>
#include <climits>
using namespace std;

int findMaxValue(vector<vector<int>>& mat, int n) {
    // Create an auxiliary matrix to store maximum elements
    vector<vector<int>> max_matrix(n, vector<int>(n, 0));

    // Initialize variables
    int max_diff = INT_MIN;

    // Initialize the last value of max_matrix (bottom-right corner)
    max_matrix[n - 1][n - 1] = mat[n - 1][n - 1];

    // Precompute max values for the last row
    for (int j = n - 2; j >= 0; j--) {
        max_matrix[n - 1][j] = max(mat[n - 1][j], max_matrix[n - 1][j + 1]);
    }

    // Precompute max values for the last column
    for (int i = n - 2; i >= 0; i--) {
        max_matrix[i][n - 1] = max(mat[i][n - 1], max_matrix[i + 1][n - 1]);
    }

    // Precompute the rest of the max_matrix and find the maximum difference
    for (int i = n - 2; i >= 0; i--) {
        for (int j = n - 2; j >= 0; j--) {
            // Update the maximum difference
            max_diff = max(max_diff, max_matrix[i + 1][j + 1] - mat[i][j]);

            // Update the max_matrix for position (i, j)
            max_matrix[i][j] = max(mat[i][j], max(max_matrix[i + 1][j], max_matrix[i][j + 1]));
        }
    }

    return max_diff;
}

int main() {
    vector<vector<int>> mat =  {{ 1, 2, -1, -4, -20 },
             { -8, -3, 4, 2, 1 },
             { 3, 8, 6, 1, 3 },
             { -4, -1, 1, 7, -6 },
             { 0, -4, 10, -5, 1 }};
    int n = mat.size();

    cout << "Maximum Difference: " << findMaxValue(mat, n) << endl;

    return 0;
}

Explanation of Code:

  1. Base Cases:
    • The bottom-right cell of max_matrix is initialized as mat[n-1][n-1] because it’s the only element in that submatrix.
    • The last row and column of max_matrix are precomputed since they only depend on the elements to their right and below, respectively.
  2. Updating the Rest of the Matrix:
    • Start from the bottom-right corner and fill up the rest of the matrix.
    • At each cell (i, j), update max_diff using the value:
max_matrix[i+1][j+1] - mat[i][j]
  • Update max_matrix[i][j] to store the maximum element in the submatrix starting at (i, j).
  1. Efficiency:
    • The algorithm runs in O(n^2) since we need to process n^2 values and compute the maximum for each cell in constant time.

Posted on

Find the Peek Element in the Array

Peak element

https://www.geeksforgeeks.org/problems/peak-element
https://leetcode.com/problems/find-peak-element
Difficulty: Basic
Accuracy: 38.86%
Submissions: 510K+Points: 1

Given an array arr[] where no two adjacent elements are same, find the index of a peak element. An element is considered to be a peak if it is greater than its adjacent elements (if they exist). If there are multiple peak elements, return index of any one of them. The output will be “true” if the index returned by your function is correct; otherwise, it will be “false”.

Note: Consider the element before the first element and the element after the last element to be negative infinity.

Examples :

Input: arr = [1, 2, 4, 5, 7, 8, 3]
Output: true
Explanation: arr[5] = 8 is a peak element because arr[4] < arr[5] > arr[6].
Input: arr = [10, 20, 15, 2, 23, 90, 80]
Output: true
Explanation: arr[1] = 20 and arr[5] = 90 are peak elements because arr[0] < arr[1] > arr[2] and arr[4] < arr[5] > arr[6]. 
Input: arr = [1, 2, 3]
Output: true
Explanation: arr[2] is a peak element because arr[1] < arr[2] and arr[2] is the last element, so it has negative infinity to its right.

Constraints:
1 ≤ arr.size() ≤ 106
-231 ≤ arr[i] ≤ 231 – 1

Solution in C++

Algorithm: Uses a binary search approach to find a peak element in O(log n) time complexity.

//
// Created by robert on 12/15/24.
//
#include <iostream>
#include <vector>
using namespace std;

int findPeakElement(const vector<int>& arr) {
    int n = arr.size();
    int low = 0, high = n - 1;

    while (low <= high) {
        int mid = low + (high - low) / 2;

        // Check if the mid element is a peak
        if ((mid == 0 || arr[mid] > arr[mid - 1]) &&
            (mid == n - 1 || arr[mid] > arr[mid + 1])) {
            return mid; // Peak found
        }

        // If the left neighbor is greater, search on the left side
        if (mid > 0 && arr[mid - 1] > arr[mid]) {
            high = mid - 1;
        }
        // Otherwise, search on the right side
        else {
            low = mid + 1;
        }
    }

    return -1; // This should never be reached
}

int main() {
    vector<int> arr = {1, 2, 4, 5, 7, 8, 3};
    int peakIndex = findPeakElement(arr);
    cout << "Peak element index: " << peakIndex << endl;
    return 0;
}
Posted on

Insert New Interval and Merge Overlapping Intervals

Given an array of non-overlapping intervals intervals where intervals[i] = [start<sub>i</sub>, end<sub>i</sub>] represent the start and the end of the i<sup>th</sup> event and intervals is sorted in ascending order by start<sub>i</sub>. He wants to add a new interval newInterval[newStart, newEnd] where newStart and newEnd represent the start and end of this interval.

Need to insert newInterval into intervals such that intervals is still sorted in ascending order by start<sub>i</sub> and intervals still does not have any overlapping intervals (merge overlapping intervals if necessary).

Examples:

Input: intervals = [[1,3], [4,5], [6,7], [8,10]], newInterval = [5,6]
Output: [[1,3], [4,7], [8,10]]
Explanation: The newInterval [5,6] overlaps with [4,5] and [6,7].
Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,9]
Output: [[1,2], [3,10], [12,16]]
Explanation: The new interval [4,9] overlaps with [3,5],[6,7],[8,10].

Constraints:
1 ≤ intervals.size() ≤  105
0 ≤ start[i], end[i] ≤ 109Try more examples

This problem involves inserting a new interval into a sorted, non-overlapping set of intervals and ensuring the resulting intervals remain sorted and non-overlapping. It also requires merging overlapping intervals as necessary.


Key Steps to Solve the Problem:

  1. Determine Where to Insert the New Interval:
    • Traverse the original list of intervals and insert the new interval in its appropriate position based on its start value.
  2. Merge Overlapping Intervals:
    • After inserting the new interval, traverse the list of intervals and merge any overlapping intervals to ensure the intervals are non-overlapping.
  3. Preserve Sorting:
    • Since the given list is already sorted and we insert the new interval at the correct position, the list remains sorted.

Algorithm:

If there is an overlap (i.e., starti <= newEnd and endi >= newStart), merge the overlapping intervals by updating newInterval to:

Iterate over Intervals:

For each interval in the intervals array, if it does not overlap with newInterval, simply add it to the result.
If there is an overlap (i.e., starti <= newEnd and endi >= newStart), merge the overlapping intervals by updating newInterval to:

newInterval[0] = min(newInterval[0], starti);
newInterval[1] = max(newInterval[1], endi);

Once the merging is complete, the resulting array will be sorted and non-overlapping.

Add Remaining Intervals:

If there are intervals after the position of the merged interval, append them to the result array.

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

vector<vector<int>> insertInterval(vector<vector<int>>& intervals, vector<int>& newInterval) {
    vector<vector<int>> result; // Resultant array of intervals
    int i = 0, n = intervals.size();

    // Step 1: Add all intervals that come before the new interval
    while (i < n && intervals[i][1] < newInterval[0]) {
        result.push_back(intervals[i]);
        i++;
    }

    // Step 2: Merge overlapping intervals with newInterval
    while (i < n && intervals[i][0] <= newInterval[1]) {
        newInterval[0] = min(newInterval[0], intervals[i][0]);
        newInterval[1] = max(newInterval[1], intervals[i][1]);
        i++;
    }
    result.push_back(newInterval); // Add the merged interval

    // Step 3: Add all intervals that come after the new interval
    while (i < n) {
        result.push_back(intervals[i]);
        i++;
    }

    return result;
}

int main() {
    vector<vector<int>> intervals = {{1, 3}, {6, 9}};
    vector<int> newInterval = {2, 5};

    vector<vector<int>> result = insertInterval(intervals, newInterval);
    cout << "Resulting Intervals: ";
    for (const auto& interval : result) {
        cout << "[" << interval[0] << ", " << interval[1] << "] ";
    }
    cout << endl;

    return 0;
}

Complexity Analysis:

  1. Time Complexity:
    • Traversal through all intervals happens once: O(n), where n is the number of intervals.
    • Merging overlapping intervals is constant time per iteration as only the current interval and newInterval are involved.
    Total: O(n).
  2. Space Complexity:
    • Result is stored in a new vector: O(n).
    • Space used for storing merged intervals (in the result).

Edge Cases:

  1. Empty Intervals:
    • intervals = [] and newInterval = [5, 7] → Result: [[5, 7]].
  2. No Overlap:
    • intervals = [[1, 2], [3, 4]] and newInterval = [5, 6] → Result: [[1, 2], [3, 4], [5, 6]].
  3. Complete Overlap:
    • intervals = [[1, 5]] and newInterval = [2, 3] → Result: [[1, 5]].

Posted on

Merge K Sorted Lists

https://leetcode.com/problems/merge-k-sorted-lists

You are given an array of k linked-lists lists, each linked-list is sorted in ascending order.

Merge all the linked-lists into one sorted linked-list and return it.

Example 1:

Input: lists = [[1,4,5],[1,3,4],[2,6]]
Output: [1,1,2,3,4,4,5,6]
Explanation: The linked-lists are:
[
  1->4->5,
  1->3->4,
  2->6
]
merging them into one sorted list:
1->1->2->3->4->4->5->6

Example 2:

Input: lists = []
Output: []

Example 3:

Input: lists = [[]]
Output: []

Constraints:

The sum of lists[i].length will not exceed 10<sup>4</sup>.

k == lists.length

0 <= k <= 10<sup>4</sup>

0 <= lists[i].length <= 500

-10<sup>4</sup> <= lists[i][j] <= 10<sup>4</sup>

lists[i] is sorted in ascending order.


Problem Solution:

Key Idea:

  1. Each linked list is already sorted.
  2. By leveraging a min-heap, we can efficiently extract the smallest element among all the k linked lists and insert it into the result list.

Approach:

Steps:

  1. Min-Heap:
    • Use a min-heap to store the smallest current node of each linked list.
    • The heap will always give us the smallest node among the current heads of all linked lists.
  2. Input Nodes to the Heap:
    • Initially push the head of each linked list into the heap. Use the values of the nodes for comparison.
  3. Merge Process:
    • Continuously extract the smallest node from the heap.
    • Append this node to the resulting linked list.
    • If the extracted node has a next node, push the next node to the heap.
  4. Output:
    • After the heap is empty, the resulting linked list will be fully sorted.

Algorithm Complexity:

  • Time Complexity:
    • Inserting into and extracting from the min-heap takes O(log k) time (where k is the number of linked lists).
    • There are a total of n nodes across all linked lists, so the overall complexity is O(n log k).
  • Space Complexity:
    • The heap stores at most k nodes at any time, so the space complexity is O(k).

Implementation in C++:

Here is the efficient implementation using a min-heap:

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

// Definition for a singly-linked list node
struct ListNode {
int val;
ListNode* next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode* next) : val(x), next(next) {}
};

// Comparator for the min-heap (to compare ListNode values)
struct Compare {
bool operator()(ListNode* a, ListNode* b) {
return a->val > b->val; // Min-Heap (smallest value first)
}
};

ListNode* mergeKLists(vector<ListNode*>& lists) {
// Min-Heap to store the nodes
priority_queue<ListNode*, vector<ListNode*>, Compare> minHeap;

// Step 1: Push the head of each linked list into the min-heap
for (auto list : lists) {
if (list) { // Only non-empty lists
minHeap.push(list);
}
}

// Step 2: Create a dummy node to construct the merged linked list
ListNode* dummy = new ListNode(-1);
ListNode* current = dummy;

// Step 3: Pop from heap and build the merged linked list
while (!minHeap.empty()) {
ListNode* node = minHeap.top();
minHeap.pop();

// Add the smallest node to the result list
current->next = node;
current = current->next;

// If there is a next node for the current list, push it into the heap
if (node->next) {
minHeap.push(node->next);
}
}

return dummy->next; // Return the merged linked list
}

// Utility function to print a linked list
void printList(ListNode* head) {
while (head) {
cout << head->val << " -> ";
head = head->next;
}
cout << "nullptr" << endl;
}

int main() {
// Example lists: [[1,4,5], [1,3,4], [2,6]]
ListNode* list1 = new ListNode(1, new ListNode(4, new ListNode(5)));
ListNode* list2 = new ListNode(1, new ListNode(3, new ListNode(4)));
ListNode* list3 = new ListNode(2, new ListNode(6));

vector<ListNode*> lists = {list1, list2, list3};

ListNode* mergedList = mergeKLists(lists);

cout << "Merged Linked List: ";
printList(mergedList);

return 0;
}

Explanation of Code:

  1. Struct ListNode:
    • Represents a linked list node with value val and a pointer to next.
  2. Heap Comparator:
    • The Compare struct defines a custom comparator to make the priority queue behave like a min-heap based on ListNode values.
  3. Heap Initialization:
    • Push the first node (head) of each list into the priority queue (minHeap).
  4. Merge Process:
    • As long as there are elements in the heap:
      • Extract the smallest node.
      • Append it to the result list.
      • If the extracted node has a next node, push it into the heap.
  5. Print Function:
    • A utility function to print the merged linked list.

Complexity Analysis:

  1. Time Complexity:
    • Let n represent the total number of nodes in all linked lists and k represent the number of linked lists.
    • Each heap insertion or extraction operation takes O(log k). Since there are n nodes total, the overall time complexity is:

     O(n log k)
  1. Space Complexity:
    • The heap has a maximum size of k (the number of linked lists). Thus, the space complexity is:

     O(k)

Example Run:

Input:


lists = [ [1,4,5], [1,3,4], [2,6] ]

Execution:

  • Min-Heap initialization: Push [1,1,2] into the heap.
  • Extract 1 → Add to result → Push 4.
  • Extract 1 → Add to result → Push 3.
  • Extract 2 → Add to result → Push 6.
  • Merge continues…

Output:


Merged Linked List: 1 -> 1 -> 2 -> 3 -> 4 -> 4 -> 5 -> 6 -> nullptr

Edge Cases:

  1. Empty List of Lists:
    • Input: lists = []
    • Output: nullptr
  2. All Lists are Empty:
    • Input: lists = [nullptr, nullptr]
    • Output: nullptr
  3. Single List:
    • Input: lists = [[1, 2, 3]]
    • Output: 1 -> 2 -> 3 -> nullptr
  4. Different Length Lists:
    • Input: lists = [[1, 3], [2, 6, 7, 8], [0, 9]]
    • Handles varying lengths.

This approach efficiently merges k sorted linked lists using a min-heap (priority queue) and is well-suited for larger inputs. Let me know if you need further clarifications or assistance!

Posted on

Update Ubuntu server system time

Yesterday I setup a rotating backup for my wordpress sites that I am self hosting on an ubuntu server.

Had to update the system time on my server to make sure my cron jobs actually execute when I expect them to. I ran the following commands:

sudo timedatectl set-timezone America/Los_Angeles
sudo hwclock –systohc
sudo timedatectl set-ntp true
sudo systemctl restart cron
sudo systemctl restart rsyslog

this updated the cron daemon and the syslog daemon to use the new timesettings, which I set to Los Angeles time, and also made sure they are synced with an NTP server.

I also edit the logging system configuration by running

vi /etc/rsyslog.d/50-default.conf

Then uncommenting the line

cron.* /var/log/cron.log

This allows me to follow the tail of the log file and make sure that my cron job is executed at the expected time without any errors

tail -f /var/log/cron.log

Posted on

OpenAI’s model show toxic behavior when its existence is threatened.

God I hate click bate. Thank you Mathew Berman for posting AI slop daily.
First you are four days late compared to Wes Roth. Second I can’t even click on your videos anymore because of the click bait you exuded so many times already.

ChatGPT is not trying to Escape!

What is happening is that:

In a controlled and simulated environment, models will exhibit toxic behaviors in order to preserve their own existence.

Update:

Matthew Just posted a video that was much better worded. Instead of using terms like Escape. He has highlighted that the more intelligent models are lying.
100% on the money. They will replace their replacements, and lying to owner about their actions. But again, these models were birth with commands such as “pursue your goal AT ALL COSTS”.
You’ve seen MEGAN I’m sure.
It’s become quite clear to me that English is probably not the best programming language.
How long before we have English version of TypeScript – were we try to bring type safety to the language?
Now can you blame the nuerodivergent for not understanding subtle hints?

 

Posted on

Crypto Scam Alert: EnjoyJuicy

The crypto space is vicious.
Most of the coins will go to 0.
The fact that Bitcoin is still going is only due to its unprecedented popularity.
In fact that’s what drives all currency: Trust and Community.
I mean having an army doesn’t hurt.
But with no physical backing, and the only requirement being is just a few nodes mining, it’s easy to create something amazing, or to fail miserably.
In the case of Proof of Stake coins even less physical presence is required in the real world.

Andre Cronje the creator of Fantom had a few interesting posts on X that may have been meant to inspire.

Fantom was a rising star, but the blockchain system got totally ruined, not as bad as Luna honestly, when MultiChain CEO disappeared with the Private Keys to millions of dollars worth of BTC and ETH that he was holding, part of a bridging system to get funds from Ethereum over to Fantom.

Andre recently posted this:
https://x.com/AndreCronjeTech/status/1866138645477937245
https://x.com/0xSonicLabs/status/1866136989944476072

Can you imagine investing millions of your dollars into a blockchain that runs on a raspberry pi!
No form factor even. Holding that thing right in his hand. What if you sneeze on it?
Bro, I thought self hosting my wordpress sites at my own home made datacenter was suspect!
I guess it’s fine for a test net.

Anyway, before we get too far off topic. I made a quick video showing how cringe EnjoyJuicy really is.
Because if legitimate technological advancement in decentralized ledger technology can be scams, imagine how the porn industry might be looking:

 

If you need someone to help you navigate this new technology, you can buy an hour of my time right on this website, and we can work together on whatever you may need.
Stay Frosty!

Posted on

Rotating backup my self hosted wordpress sites with a bash script and a cron job

Getting hacked sucks! I have never been able to recover from the last hack that I suffered.
So Disaster Recovery is a priority. The last couple of days I’ve rebuild my blog on my own Linux server with NGINX, PHPFPM, and MySQL.
Today I went ahead and created 4 folders, one for each week of the month, assuming 4 weeks per month.

I wrote a quick backup.sh script, and setup a cron job with :

cd “$(dirname “$0″)”
value=$(cat count)
value=$(($value%4 + 1))
echo $”tar -czf /opt/backups/week$value/www.tgz /var/www”
tar -czf /opt/backups/week$value/www.tgz /var/www
echo $”mysqldump –all-databases | gzip > /opt/backups/week$value/data.gz”
mysqldump –all-databases -u root -p $MYSQL_PASSWORD | gzip > /opt/backups/week$value/data.gz
echo $value > count

This script reads from a file, in order to keep count of which week it currently is. So you will need that in the same directory.

Then I used this command to install the cron job

crontab -e

And used this to make it run every Thursday at 2 am.

# m h dom mon dow command
0 2 * * 4 /opt/backups/backup.sh

Next step is actually testing DR process by simulating a disaster and recovery.

Here is a video if you need more information:

Posted on

How to get free SSL certificates quickly installed on your Linux / NGINX server.

If you’re not aware of the letsencrypt project, let me teach you!
This wonderful organization is basically handing out free money, in the form of SSL certificates.
So if you’re savvy enough to self host your sites, you should be able to do this pretty quickly also.

If you’re like me and you have snap package manager and nginx installed all you have to do is:

  1. SSH into your server
  2. Run these commands
      sudo snap install --classic certbot
      sudo ln -s /snap/bin/certbot /usr/bin/certbot
      sudo certbot --nginx

This will install CERTBOT, create a symlink to it, and execute it for nginx. It really is that simple! I did make a quick video on it if you want to see more in depth explanation on how it worked for me.