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.

Posted on

are you a logger?

Some people are debuggers.
Stepping their way through the binary jungle, one hack at a time.

For those of you who are loggers, staring  at the console for interesting events:
I had some time to write a small php script that will put a console.log for every method in a canjs controller.

Should save me loads of monotony when reverse engineering OPC ( other peoples code ).

Hope you find it useful:

<?php

if( !isset( $argv[1] ) )
$argv[1] = 'Storage.js';

$fileInfo = pathinfo( $argv[1] );
$outFile = $fileInfo['dirname'] . '/' . $fileInfo['filename'] . '_debug.' . $fileInfo['extension'];

$in = fopen($argv[1], 'r');
$out = fopen($outFile, 'w');

while( !feof( $in ) ){
$line = fgets($in);
if( preg_match('/:\W+function/', $line)){
preg_match("/\((.*)\)/", $line, $matches);
$function = explode(':', $line );
$functionName = trim($function[0]);

if( isset( $matches[1] ) && strlen($matches[1]) > 0  )
$line .= "\nconsole.log( '$fileInfo[filename]', '$functionName', $matches[1] )\n";
else
$line .= "\nconsole.log( '$fileInfo[filename]', '$functionName' )\n";
}
fputs($out, $line);
}

fclose($in);
fclose($out);

Posted on

No Privacy Question for Google

Google backed up my phone’s photos and videos and went ahead and created a public album.
I guess you call this Auto Aware, well this feature is a huge violation of my privacy, and I don’t want to have this feature enabled any more.

I want my photos and videos not to be backed up. Only my contacts.
What is happening with my text messages? Is google reading them?
I bought Nike shoes and got a receipt email from Nordstrom’s and next thing I know Google+ is showing me some Nike content.
CREEPY!

You are like the stalker boyfriend of my nightmares. Can I opt out of this feature too?

Also I noticed that I have very private reviews of businesses visible on Google plus.
This is another privacy concern for me.

I don’t want everyone knowing what I have been doing all the time unless I willingly POST that information.
Please stop syphoning out content from my phone, and my other activities on other Google properties, and making them public.

Next thing you know you will be sharing my private searches with my friends, or telling them to call me cause I searched “lonely” or something like that.
I don’t need it. I don’t want it. Let me run my life, and stay out of my business.

How many god awful features are there, and how do I opt out of them?

Posted on

fs-hogan == mustache.java (almost)

So lately I have been working on creating a mustache renderer in NodeJS.
My biggest challenge was finding a NodeJS module that had mustache rendering implemented closely to its Java counterpart.

I was able to find Hogan.js, the mustache renderer done by the twitter guys.
As great and powerful as Hogan.js is, initially I was a little disappointed that it was designed to run in the browser.

That meant no Filesystem operations were allowed. This is kind of like the difference between mustache.js and mu2.js. mu2.js is the NodeJS version, where partials are loaded and parsed from the filesystem, versus mustache.js, where an in memory collection of partials is used to pull from.

Well, Robert Sayer told me that I should just search NPM, and that I would find more than one “fork” of their Hogan.js.
He was right, I quickly found fs-hogan.js which did everything I needed.

The only other difference I have to note between Mustache.Java and FS-Hogan is the use of the {{.}} implicit iterator.
In the Java version, having a data model like:

{title:”some title”}

will render this template

{{#title}} <h2> {{.}} </h2> {{/title}}

without any issues into

<h2> some title </h2>

I can totally see why Sam Pullara made it work like that. Its really easy syntax to follow, and looks very elegant. Unfortunately the same thing will not render in FS-Hogan, you will get:

<h2> </h2>

To get the same result in both Mustache.Java and FS-Hogan, you must use this syntax:

{{#title}}<h2>{{title}}</h2>{{/title}}

 

Big shout out to Robert Sayer and Sam Pullara, thanks for  all your hard work guys!