Leetcode - Capacity To Ship Packages Within D Days - Two Solutions

Here are my two solutions to today's Leetcode problem:

Both solutions use binary search, they are inspired by this solution, with slight performance improvements. Both of them rely on a greedy algorithm and binary search.

Solution 1:

This solution beats 98.92% of solutions in terms of runtime speed but only 21.8% in terms of memory usage.

const isPossible = (weights, days, maxShipSize) => {
  let currentDay = 1;
  let sumOfWeights = 0;

  for (let i = 0; i < weights.length; i++) {
    const weight = weights[i];
    const newSum = sumOfWeights + weight;

    if (newSum > maxShipSize) {
      sumOfWeights = weight;
      currentDay += 1;
    } else {
      sumOfWeights = newSum;
    }

    if (currentDay > days) {
      return false;
    }
  }

  if (currentDay <= days) {
    return maxShipSize;
  }

  return true;
};

function shipWithinDays(weights, days) {
  let left = Math.max(...weights);
  let right = weights.reduce((a, b) => a + b, 0);

  while (left < right) {
    const mid = Math.floor((left + right) / 2);

    if (isPossible(weights, days, mid)) {
      right = mid;
    } else {
      left = mid + 1;
    }
  }

  return left;
}

Solution 2

This one is slightly more balanced - it beats 64.87% of solutions in terms of runtime and 79.46% in terms of memory usage.

const isPossible = (weights, days, maxShipSize) => {
  let currentDay = 1;
  let sumOfWeights = 0;

  for (let i = 0; i < weights.length; i++) {
    const weight = weights[i];
    const newSum = sumOfWeights + weight;

    if (weight > maxShipSize) {
      return false;
    }

    if (newSum > maxShipSize) {
      sumOfWeights = weight;
      currentDay += 1;
    } else {
      sumOfWeights = newSum;
    }

    if (currentDay > days) {
      return false;
    }
  }

  if (currentDay <= days) {
    return maxShipSize;
  }

  return true;
};

function shipWithinDays(weights, days) {
  let left = 0;
  let right = weights.reduce((a, b) => a + b, 0);

  while (left < right) {
    const mid = Math.floor((left + right) / 2);

    if (isPossible(weights, days, mid)) {
      right = mid;
    } else {
      left = mid + 1;
    }
  }

  return left;
}

Explore related topics

leetcodeprogramming
reply

Other posts you might like

successful spells and potions. Leetcode problem: https://leetcode.com/problems/successful-pairs-of-spells-and-potions/description/

--------------------

Input: spells = [5,1,3], potions = [1,2,3,4,5], success = 7 Output: [4,0,3] Explanation:

  • 0th spell: 5 * [1,2,3,4,5] = [5,10,15,20,25]. 4 pairs are successful.
  • 1st spell: 1 * [1,2,3,4,5] = [1,2,3,4,5]. 0 pairs are successful.
  • 2nd spell: 3 * [1,2,3,4,5] = [3,6,9,12,15]. 3 pairs are successful. Thus, [4,0,3] is returned.

Intuition

My initial intuition (and I assume for many others out there), when seeing the problem, is to multiply each spell by each potion in the potions array, return the number of successful pairs and continue in this way. Unfortunately, this leads to a time complexity of O(n * m) which will not work for bigger inputs. In order to change the time complexity from O(n*m) to O(n * log(m)) we have to use a binary search to minimize the number of searches through the potions array we have to do.

Approach

We initiate a helper function called spellAndPotions which accepts a single spell, an array of potions and success/target number. It returns a number "successfulPairs" which is a counter for the number of successfulPairs of a single spell * potion in the potion array. The spellAndPotions function uses binary search in order to minimize the number of potions it has to analyze, therefore it expects the potions array to be sorted for the input.

successfulPairs function is initiated and accepts a spells ...

reply

Leetcode - Add Two Numbers - Two Solutions

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list.

Full problem here.

Solution 1. Based on this solution

var addTwoNumbers = function(l1, l2) {
    const head = new ListNode(0)

    let firstNode = l1
    let secondNode = l2
    let currentNode = head
    let carry = 0

    while (firstNode || secondNode || carry) {
        const firstValue = firstNode?.val || 0
        const secondValue = secondNode?.val || 0
leetcodeprogrammingjavascriptrecursionlinked listsdata structures
reply

When someone says AI will steal everybody's jobs

const symbols = {
"I": 1,
"V": 5,
"X": 10,
"L": 50,
"C": 100,
"D": 500,
"M": 1000
};

const romanToInt = function(s) {
let value = 0;
for (let i = 0; i < s.length - 1; i++) {
console.log("s", s[i])
console.log("s+1", s[i+1])
symbols[s[i]] < symbols[s[i+1]] ? value -= symbols[s[i]]: value += symbols[s[i]];
reply

How I struggled to fix votes on Sanity

Ever since I implemented upvotes a few months ago, I had been struggling with user upvotes/downvotes request occasionly timing out. The bug persisted for a few months and the few times I tried to debug it, I had no success. Is it the database schema? Nope, I use similar schemas for other collections and they work fine. An inefficient MongoDB query? Same thing. No indexing? I indexed the DB even though there are barely any votes in the collection. An issue with Vercel cold start? Also not it, everything within the norm.

Last Friday the rest of the app was finally ready and I wanted to start inviting some users, so I gave up and decided to pay $20/month for Vercel Pro to increase the timeout from 10 to 60 seconds and worry about the bug another day. And then I checked the logs on Vercel Pro...

Unhandled error: MongooseError: Operation `userVotes.findOne()` buffering timed out after 10000ms
    at Timeout.<anonymous> (/var/task/sanity_client/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:175:23)
    at listOnTimeout (node:internal/timers:569:17)
    at process.processTimers (node:internal/timers:512:7)

Because Mongoose timeout is 10000ms and Vercel's timeout is also 10000ms but this includes the cold start time, this error never popped up on my free plan....

sanityprogrammingvercelmongodbbuilding in public
reply

How I implemented slugs on Sanity - a TypeScript code sample

The lack of human-readable slugs on Sanity had bothered me for a while and I finally got around to fixing them last Sunday. The old, slugless URL structure probably wasn't doing me any favors in terms of SEO and user experience. I'm hoping the new format can give Sanity a much needed SEO boost. Plus, I can finally tell which post is which in Google Search Console and Vercel Analytics.

The Result

Before

https://www.sanity.media/p/64c375049f5d6b05859f10c6

After

https://www.sanity.media/p/64c375049f5d6b05859f10c6-delicious-post-workout-milkshake-recipe

Isn't this much clearer?

The Code

When writing the code I had the following goals in mind:

programmingjavascriptmongoosebuilding in publicmongodb
1 comment

Fixing AWS Timestream query

My 'ago' function had been failing with "The query syntax is invalid" error on the following clause:

time BETWEEN ago(24h5m) AND ago(24h) AND

I fixed it by changing converting the hours to minutes:

time BETWEEN ago(1445m) AND ago(1440m) AND

programmingaws timestreamsqlawsamazon web services
reply

How I Managed My Hunger and Improved My Diet

The saying, "You are what you eat," rings true when it comes to our health. The food we consume fuels everything we do, be it work, hobbies, or day-to-day living. Whether it's mental acuity or physical strength you're after, it all traces back to your diet.

If you're still not convinced, let me share my food journey with you.

I didn't always have a problem with my diet. Like many of us, I grew accustomed to my eating habits. If there didn't seem to be any immediate issues with my diet, why should I bother fixing something that wasn't broken?

My dietary journey began when I started researching blue zones – areas where people tend to live exceptionally long lives. My partner and I were intrigued to discover that most residents of these zones followed primarily vegetarian diets, with occasional additions of meat or fish. Noticing this, we decided to incorporate mostly vegetarian foods into our meals. Although I've oscillated between vegetarianism and veganism over the years, I often felt very hungry on these diets. In fact, when I resumed a vegetarian diet, I wasn't feeling my best and noticed increased hunger compared to when I was on an omnivorous diet.

The next phase of my journey was prompted by an unexpected change. Despite not gaining a significant amount of weight after switching my diet, I felt softer, as if I was losing muscle and gaining fat. Dissatisfied with this shift, I turned to the advice of Stephen Zimm, a prof...

healthfitnesssugar addictionhigh protein dietnon restrictive dieting
1 comment

How I built a chat app using Streams API, Next.JS, Redis and Vercel

Last week I added a chat feature to Sanity. In this article, I'll guide through how I built it using Streams API, Next.js, Redis and Vercel.

Sanity chat

Before we start, a quick disclaimer: there are much better ways to build a chat application, for example by using WebSockets. Vercel unfortunately doesn't support WebSockets and I didn't want to spin a dedicated server, which is why I used Streams API. Using Streams API the way I use it here is most likely not the best use of resources but it works and is a good enough solution for my small scale use. If you're on the same boat, keep reading.

If the chat takes off, I'll have to move it to a dedicated Socket.io server, a serverless WebSocket on AWS, or something similar to reduce costs.

Storing messages in Redis

I use the KV (Redis) database from Vercel to store the last 100 messages. Here is the code used to send and read messages.

import { MAX_CHAT_MESSAGE_LENGTH } from "@/utils";

const MAX_MESSAGES = 100;

export const addChatMessage = async ({
programmingvercelstreams apibackendnext.jsreactredisjavascript
reply

How I fixed @aws-crypto build error

I've been getting the following error when building my Next.js app:

Failed to compile.

./node_modules/.pnpm/@aws-crypto+sha256-js@5.2.0/node_modules/@aws-crypto/sha256-js/build/module/index.js + 12 modules Cannot get final name for export 'fromUtf8' of ./node_modules/.pnpm/@smithy+util-utf8@2.0.2/node_modules/@smithy/util-utf8/dist-es/index.js

I narrowed the source down to the following piece of code:

import { createServerRunner } from "@aws-amplify/adapter-nextjs";
import { AWS_AMPLIFY_CONFIG } from "./utils";
import { cookies } from "next/headers";
import { getCurrentUser } from "aws-amplify/auth/server";

export const { runWithAmplifyServerContext } = createServerRunner({
  config: AWS_AMPLIFY_CONFIG,
});
awsnext.js@aws-cryptoamplifyprogramming
reply
feedback