<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lokeswaran Aruljothi</title>
    <description>The latest articles on DEV Community by Lokeswaran Aruljothi (@lokeswaran-aj).</description>
    <link>https://dev.to/lokeswaran-aj</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F693549%2F73f73598-d499-4b2b-bef5-4b1454c6ebd4.jpeg</url>
      <title>DEV Community: Lokeswaran Aruljothi</title>
      <link>https://dev.to/lokeswaran-aj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lokeswaran-aj"/>
    <language>en</language>
    <item>
      <title>How Large Language Models Work: A Simple Overview for Beginners</title>
      <dc:creator>Lokeswaran Aruljothi</dc:creator>
      <pubDate>Fri, 02 Jan 2026 15:03:05 +0000</pubDate>
      <link>https://dev.to/lokeswaran-aj/how-large-language-models-work-a-simple-overview-for-beginners-1558</link>
      <guid>https://dev.to/lokeswaran-aj/how-large-language-models-work-a-simple-overview-for-beginners-1558</guid>
      <description>&lt;h3&gt;
  
  
  TLDR;
&lt;/h3&gt;

&lt;p&gt;When you give text to an LLM, it first splits it into tokens using &lt;strong&gt;tokenization&lt;/strong&gt;, and those tokens are converted into &lt;strong&gt;embeddings&lt;/strong&gt;. Each token compares itself with other tokens using &lt;strong&gt;attention&lt;/strong&gt; to build meaningful context. The model then generates raw scores for all possible next tokens and converts them into a &lt;strong&gt;probability distribution&lt;/strong&gt;. Finally, &lt;strong&gt;sampling&lt;/strong&gt; selects the next token. This &lt;strong&gt;autoregressive loop&lt;/strong&gt; continues until the LLM produces a complete response.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is an LLM?
&lt;/h3&gt;

&lt;p&gt;A large language model is, at its core, a next-token prediction system. Given some input text, it predicts the most likely next token, appends it to the input, and repeats this process in a loop to generate a response. At each step, the model effectively asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the most probable next token that will follow this input?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An LLM does not understand text or language in the way humans do. The text you provide is first converted into numbers, and the model operates entirely on those numerical representations. Rather than understanding meaning, the model learns statistical patterns in language and uses those patterns to predict what token is likely to come next.&lt;/p&gt;

&lt;p&gt;Since an LLM operates only on numbers, the text we provide cannot be used directly. The first step is to break text into smaller units called tokens, which act as the building blocks for everything that follows. This process is known as &lt;strong&gt;tokenization&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Tokenization: Breaking text into model-friendly pieces
&lt;/h3&gt;

&lt;p&gt;Each language model has a fixed vocabulary, which is a list of tokens it knows how to work with. Every token is mapped to a numeric value called a token ID. Tokens can represent full words, parts of words, punctuation, whitespace, or even common character sequences. Internally, the model never sees raw text, it only sees these token IDs.&lt;/p&gt;

&lt;p&gt;When text is passed to the model, it is split into tokens based on the tokenizer and vocabulary used by that specific model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9l0rf12wv67z0r02imv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9l0rf12wv67z0r02imv.png" alt="Tokenization" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, in the image above, the sentence is tokenized using the &lt;a href="https://tiktokenizer.vercel.app/" rel="noopener noreferrer"&gt;GPT‑4o tokenizer&lt;/a&gt;. Notice how the word “&lt;em&gt;microservices&lt;/em&gt;” is split into multiple tokens rather than treated as a single word. This happens because tokenizers often use subword units to efficiently handle large and diverse vocabularies.&lt;/p&gt;

&lt;p&gt;Because different models use different tokenizers and vocabularies, the same sentence can be split into tokens differently across models. This is why token counts vary and why the same input may consume more or fewer tokens depending on the model being used.&lt;/p&gt;

&lt;p&gt;On their own, tokens are still just numbers with no inherent meaning. To represent relationships and semantics, these tokens are next converted into &lt;strong&gt;embeddings.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Embeddings: Turning tokens into vectors
&lt;/h3&gt;

&lt;p&gt;The tokenizer converts input text into tokens and maps them to token IDs. However, these token IDs are just numbers and carry no inherent meaning. The model cannot reason or operate using these raw IDs alone. This is where embeddings come into the picture.&lt;/p&gt;

&lt;p&gt;An embedding is a vector representation of a token. Each token ID is mapped to a dense vector that captures semantic information. Tokens with similar meanings tend to have similar embeddings, which allows the model to reason about language in a more meaningful way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhz7uisrlq8rlirztykcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhz7uisrlq8rlirztykcw.png" alt="Vector embedding" width="800" height="756"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above shows a simplified visualization of embeddings. Words like “king” and “prince” appear close to each other, as do “father” and “son”, while “mother” and “daughter” form a separate group. This illustrates how embeddings can capture semantic similarities and relationships. In reality, embeddings exist in a multi-dimensional space, not just two or three dimensions, and the axes shown here are only for intuition.&lt;/p&gt;

&lt;p&gt;You can think of an embedding as a point in a multi-dimensional space. Tokenization gives a token ID, and that ID is used to look up the corresponding embedding vector. At this stage, each token is represented independently. Tokens do not yet interact with one another, and no context has been applied.&lt;/p&gt;

&lt;p&gt;Along with token embeddings, positional information is added so the model knows the order of tokens in the sequence. This ensures that the model can distinguish between different word orders, such as “the sky is blue” and “blue is the sky”.&lt;/p&gt;

&lt;p&gt;At this point, tokens have semantic meaning, but they still do not understand the full context of the sentence. Each token is aware only of itself. To understand language, tokens must relate to one another and determine which other tokens are relevant. This is achieved using &lt;strong&gt;attention&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Attention: Relating tokens to each other
&lt;/h3&gt;

&lt;p&gt;Attention allows each token to look at other tokens in the input and decide how important they are for understanding the current context. Instead of treating all tokens equally, the model learns which tokens should influence each other and by how much. This process enables the model to build context-aware representations of each token.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycx09kwt3eelpwr3mfvt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycx09kwt3eelpwr3mfvt.png" alt="each token sends connections to other tokens. Stronger connections indicate that one token considers another token more relevant when building its contextual meaning. This process happens for every token in the input sequence" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the visualization above, each token sends connections to other tokens. Stronger connections indicate that one token considers another token more relevant when building its contextual meaning. This process happens for every token in the input sequence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Queries, Keys, and Values
&lt;/h3&gt;

&lt;p&gt;To compute attention, each token is transformed into three different representations called &lt;strong&gt;query&lt;/strong&gt;, &lt;strong&gt;key&lt;/strong&gt;, and &lt;strong&gt;value&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;query&lt;/strong&gt; represents what the current token is looking for.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;key&lt;/strong&gt; represents what other tokens offer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;value&lt;/strong&gt; represents the information carried by those tokens.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The query of one token is compared with the keys of all other tokens to measure relevance. Based on this relevance, the corresponding values are combined with different strengths to produce a new, context-aware representation for the token. This is the core idea behind attention. The goal is not to perform a lookup, but to determine which tokens matter most in a given context.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-head self-attention
&lt;/h3&gt;

&lt;p&gt;This attention process does not happen just once. Instead, it runs multiple times in parallel using different attention heads. Each head can focus on different patterns in the sentence, such as grammatical structure, relationships between words, or long-range dependencies. The outputs from all heads are then combined to form a richer representation of each token. This mechanism is known as &lt;strong&gt;multi-head self-attention&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Role of the feedforward network
&lt;/h3&gt;

&lt;p&gt;After attention mixes information across tokens, the resulting representations pass through a small feedforward neural network, often called a multi-layer perceptron. This step processes each token independently and helps refine its representation further. While attention handles relationships between tokens, this network helps transform and polish the information within each token.&lt;/p&gt;

&lt;p&gt;At the end of this stage, each token is no longer isolated. It now carries information about its own meaning as well as its relationship to other tokens in the sentence. These context-aware token representations (new embeddings) are then used to compute scores for all possible next tokens in the vocabulary, which leads into &lt;strong&gt;probability estimation&lt;/strong&gt; and token selection.&lt;/p&gt;




&lt;h3&gt;
  
  
  From representations to probabilities
&lt;/h3&gt;

&lt;p&gt;Now that each token has a context-aware representation produced by attention, the model uses these representations to decide what should come next. For the current position, the model generates a score for every possible token in its vocabulary. These raw scores are called logits.&lt;/p&gt;

&lt;p&gt;Logits represent how likely each token is to be the next token, relative to the others. A higher logit means the model considers that token more likely. However, logits are not probabilities. They are not normalized, do not fall within a fixed range, and are difficult to interpret directly.&lt;/p&gt;

&lt;p&gt;To convert these logits into something meaningful, the model applies a function called &lt;a href="https://en.wikipedia.org/wiki/Softmax_function" rel="noopener noreferrer"&gt;softmax&lt;/a&gt; that transforms them into a probability distribution. After this step, each possible token is assigned a probability, and all probabilities sum to 1. This distribution represents how likely the model believes each token is to be chosen next.&lt;/p&gt;

&lt;p&gt;At this point, the model knows the likelihood of every possible next token. The remaining question is how to select one token from this distribution, which is handled by the &lt;strong&gt;sampling&lt;/strong&gt; step.&lt;/p&gt;




&lt;h3&gt;
  
  
  Sampling: choosing the next token
&lt;/h3&gt;

&lt;p&gt;After the model computes a probability distribution for the next token, it must select one token to generate. If the model always chooses the token with the highest probability, it will produce the same output every time. This often leads to repetitive and less natural output. &lt;strong&gt;Sampling&lt;/strong&gt; is used to introduce controlled randomness into the generation process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Greedy decoding (baseline)
&lt;/h3&gt;

&lt;p&gt;In greedy decoding, the model always picks the token with the highest probability. This approach is fully deterministic and produces consistent outputs. While it can be useful for tasks that require precision, it is generally not suitable for open-ended tasks such as creative writing or conversation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Temperature
&lt;/h3&gt;

&lt;p&gt;Temperature controls how sharp or flat the probability distribution is. It does not change which tokens are possible, only how likely they are relative to one another.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;lower temperature&lt;/strong&gt; makes the distribution sharper, causing high-probability tokens to dominate. This results in more confident and less random output.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;higher temperature&lt;/strong&gt; flattens the distribution, allowing lower-probability tokens to be selected more often. This increases diversity and randomness.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7jdmwqeickpsgvl8kck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7jdmwqeickpsgvl8kck.png" alt="A lower temperature makes the distribution sharper, causing high-probability tokens to dominate. This results in more confident and less random output." width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnh1wjnvxrtr5q04jgdtt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnh1wjnvxrtr5q04jgdtt.png" alt="A higher temperature flattens the distribution, allowing lower-probability tokens to be selected more often. This increases diversity and randomness." width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Top-k sampling
&lt;/h3&gt;

&lt;p&gt;Top-k sampling further restricts the choice of the next token by considering only the &lt;strong&gt;k most probable tokens&lt;/strong&gt;. All other tokens are ignored. This prevents extremely unlikely tokens from being selected while still allowing some diversity among the most likely options.&lt;/p&gt;

&lt;h3&gt;
  
  
  Top-p (nucleus sampling)
&lt;/h3&gt;

&lt;p&gt;Top-p sampling, also known as nucleus sampling, selects the smallest set of tokens whose &lt;strong&gt;cumulative probability exceeds a threshold p&lt;/strong&gt;. Unlike Top-k, this set can change dynamically depending on how confident the model is. This makes Top-p more adaptive and often better at balancing focus and diversity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvhrsy5yrgymt32ebsdem.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvhrsy5yrgymt32ebsdem.png" alt="In this example, only the most likely tokens whose probabilities sum to the chosen threshold are considered for sampling." width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, only the most likely tokens whose probabilities sum to the &lt;strong&gt;0.8&lt;/strong&gt; threshold are considered for sampling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Putting it together
&lt;/h3&gt;

&lt;p&gt;Temperature, Top-k, and Top-p are often used together. They control &lt;strong&gt;how randomness is applied&lt;/strong&gt;, not &lt;strong&gt;what the model knows&lt;/strong&gt;. The underlying probabilities remain the same, but different sampling settings lead to different generation behavior.&lt;/p&gt;

&lt;p&gt;Once a token is selected, it is appended to the input, and the entire process repeats. This is how LLMs generate text one token at a time until a complete response is produced.&lt;/p&gt;




&lt;h3&gt;
  
  
  A simple mental model
&lt;/h3&gt;

&lt;p&gt;At its core, a large language model is a system designed to predict what comes next. Everything you have seen in this blog, from tokenization, embeddings, attention, probabilities, to sampling, exists to support that single goal. The apparent intelligence of an LLM emerges not from understanding language like a human, but from repeatedly applying this prediction process at scale.&lt;/p&gt;

&lt;p&gt;Once you internalize this mental model, many behaviors of LLMs start to make sense. This explains why phrasing matters, why responses can vary, and why models sometimes sound confident yet incorrect. They are not reasoning about truth, but generating the most likely continuation based on patterns learned from data.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>openai</category>
    </item>
    <item>
      <title>Rag in production</title>
      <dc:creator>Lokeswaran Aruljothi</dc:creator>
      <pubDate>Mon, 09 Dec 2024 17:24:18 +0000</pubDate>
      <link>https://dev.to/lokeswaran-aj/rag-in-production-395o</link>
      <guid>https://dev.to/lokeswaran-aj/rag-in-production-395o</guid>
      <description></description>
      <category>rag</category>
    </item>
    <item>
      <title>Finally built a portfolio website</title>
      <dc:creator>Lokeswaran Aruljothi</dc:creator>
      <pubDate>Thu, 15 Aug 2024 14:15:06 +0000</pubDate>
      <link>https://dev.to/lokeswaran-aj/finally-built-a-portfolio-website-36fg</link>
      <guid>https://dev.to/lokeswaran-aj/finally-built-a-portfolio-website-36fg</guid>
      <description>&lt;h2&gt;
  
  
  Hello world
&lt;/h2&gt;

&lt;p&gt;As a software engineer, I have always wanted to build a portfolio website. After multiple incomplete attempts, I finally built one. Link: &lt;a href="https://lokeswaran.vercel.app/" rel="noopener noreferrer"&gt;https://lokeswaran.vercel.app/&lt;/a&gt;. This time, I took a different approach and embraced minimal design. I took inspiration from &lt;a href="https://leerob.io/" rel="noopener noreferrer"&gt;@leeerob&lt;/a&gt; and &lt;a href="https://ibelick.com/" rel="noopener noreferrer"&gt;@Ibelick&lt;/a&gt; portfolios.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Minimal Design?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Focus:&lt;/strong&gt; Prioritizing content and functionality over flashy elements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clarity:&lt;/strong&gt; A simple interface that guides users intuitively.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Completion:&lt;/strong&gt; Stripping away the non-essentials led to a project that truly reflects my skills and style.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Here's what you'll find:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;My Journey: The highs and lows that brought me here.&lt;/li&gt;
&lt;li&gt;Projects: Showcasing problem-solving skills.&lt;/li&gt;
&lt;li&gt;Blog: Thoughts on tech trends and software engineering.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Techs I used to build this
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;TailwindCSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/hashicorp/next-mdx-remote" rel="noopener noreferrer"&gt;next-mdx-remote&lt;/a&gt; for mdx blogging&lt;/li&gt;
&lt;li&gt;&lt;a href="https://buttons.ibelick.com/" rel="noopener noreferrer"&gt;Ibelick button&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://rehype-pretty.pages.dev/" rel="noopener noreferrer"&gt;rehype-pretty-code&lt;/a&gt; plugin for syntax highlighting in the blog&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt; for deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Thinks i learnt while building this
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Generating dynamic metadata for my blogs for SEO&lt;/li&gt;
&lt;li&gt;Opengraph image and generating dynamic og image in nextjs&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://github.com/hashicorp/next-mdx-remote" rel="noopener noreferrer"&gt;next-mdx-remote&lt;/a&gt; to render mdx files&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://rehype-pretty.pages.dev/" rel="noopener noreferrer"&gt;rehype-pretty-code&lt;/a&gt; plugin to render the code snippets with one-dark theme and syntax highlight code in the blog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're facing struggles with building your portfolio, my advice is simple: &lt;strong&gt;KISS&lt;/strong&gt;(Keep It Simple, Stupid).&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Graph Problems</title>
      <dc:creator>Lokeswaran Aruljothi</dc:creator>
      <pubDate>Sun, 31 Dec 2023 08:10:31 +0000</pubDate>
      <link>https://dev.to/lokeswaran-aj/graph-problems-23ed</link>
      <guid>https://dev.to/lokeswaran-aj/graph-problems-23ed</guid>
      <description>&lt;p&gt;Graph problems play a pivotal role in various fields, from computer science to logistics. Understanding and solving these problems require a diverse set of algorithms. In this blog post, we'll explore some fundamental graph problems, shedding light on their significance and presenting solutions that cater to different scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shortest Path Problem:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gIKEv4q---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6edg9m3ah8lvm919vhi2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gIKEv4q---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6edg9m3ah8lvm919vhi2.png" alt="Shortest Path Problem" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The shortest path problem revolves around finding the most efficient route between two nodes in a graph. Various methods can tackle this problem, depending on the nature of the graph:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;BFS (Unweighted Graph):&lt;/strong&gt; Ideal for unweighted graphs, BFS systematically explores neighbors to discover the shortest path.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dijkstra's Algorithm:&lt;/strong&gt; Efficient for graphs with non-negative weights, Dijkstra's algorithm optimally finds the shortest path.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bellman Ford:&lt;/strong&gt; A versatile algorithm that accommodates graphs with negative weights.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Floyd-Warshall:&lt;/strong&gt; Suitable for all-pairs shortest path problems, handling both positive and negative weights.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A*:&lt;/strong&gt; Combines aspects of Dijkstra's and greedy algorithms, optimizing pathfinding with heuristics.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Connectivity:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w-UitOrL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ubysbcd1tue3idvca6z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w-UitOrL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ubysbcd1tue3idvca6z.png" alt="Connectivity" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Determining connectivity involves establishing whether a path exists between two nodes. Here are methods tailored for different scenarios:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Union Find Data Structure:&lt;/strong&gt; Efficiently detects connectivity in disjoint sets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DFS (Depth-First Search):&lt;/strong&gt; Systematically explores the graph's depth to ascertain connectivity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;BFS (Breadth-First Search):&lt;/strong&gt; Unveils connected nodes layer by layer, aiding in connectivity analysis.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Negative Cycle:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CZFtRJyQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ba9po612cxy3zpkyc7yx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CZFtRJyQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ba9po612cxy3zpkyc7yx.png" alt="Negative Cycle" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Identifying negative cycles in weighted directed graphs is crucial. The following algorithms are adept at handling this task:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bellman Ford:&lt;/strong&gt; Detects negative cycles and their locations in the graph.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Floyd-Warshall:&lt;/strong&gt; Extensively applicable, it identifies negative cycles in the graph.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Strongly Connected Components:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fiWz9pXM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdmmxafbd70182mx8syc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fiWz9pXM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdmmxafbd70182mx8syc.png" alt="Strongly Connected Components" width="800" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Strongly connected components (SCC) are self-contained graph portions in directed graphs. The following algorithms excel in identifying SCC:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tarjan's Algorithm:&lt;/strong&gt; Effectively identifies SCC in linear time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Kosaraju's Algorithm:&lt;/strong&gt; Divides the graph into SCC, offering a comprehensive understanding.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Travel Salesman Problem:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JwfahKRc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yny6p0jc5v6wcrjpq9qc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JwfahKRc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yny6p0jc5v6wcrjpq9qc.png" alt="Travel Salesman Problem" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Traveling Salesman Problem (TSP) challenges us to find the shortest path visiting all cities exactly once. As an NP-hard problem, TSP requires sophisticated approaches:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Held-Karp with DP (Dynamic Programming):&lt;/strong&gt; Optimally solves smaller subproblems, building up to the complete solution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Branch and Bound:&lt;/strong&gt; Systematically explores potential solutions, pruning branches for efficiency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Other Approximation Algorithms like Ant Colony Optimization:&lt;/strong&gt; Leverages heuristic methods for practical solutions.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Bridges and Articulation Points:
&lt;/h2&gt;

&lt;p&gt;Bridges and articulation points highlight vulnerabilities in a graph:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FV3aSdrt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxascbvqstnr430l3gob.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FV3aSdrt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxascbvqstnr430l3gob.png" alt="Bridges and Articulation Points" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bridges:&lt;/strong&gt; Removing them increases the number of connected components, exposing critical edges.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HLOFHVao--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lnaxadlpbb5kqw1p9t3m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HLOFHVao--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lnaxadlpbb5kqw1p9t3m.png" alt="Articulation Points" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Articulation Points:&lt;/strong&gt; Their removal amplifies the number of connected components, signaling key nodes in the graph's structure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These indicators often reveal weak points, bottlenecks, or vulnerabilities in a graph.&lt;/p&gt;

&lt;h2&gt;
  
  
  Minimum Spanning Tree:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_y1dUcLA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ugfzdjlqnugf6fppwfh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_y1dUcLA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ugfzdjlqnugf6fppwfh.png" alt="Minimum Spanning Tree" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Minimum Spanning Tree (MST) connects all vertices with the least total edge weight and no cycles. Algorithms for finding MST include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Kruskal's Algorithm:&lt;/strong&gt; Greedily selects edges with the smallest weights to construct the MST.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prim's Algorithm:&lt;/strong&gt; Builds the MST incrementally, selecting the lightest edge at each step.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Boruvka's Algorithm:&lt;/strong&gt; Iteratively adds edges to the MST until all vertices are covered.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Network Flow (Max Flow):
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lIXlP-k2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/plrtwgmb9gp84mqmsxgw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lIXlP-k2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/plrtwgmb9gp84mqmsxgw.png" alt="Network Flow" width="800" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Determining the maximum flow through a network is crucial in various applications:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ford Fulkerson Algorithm:&lt;/strong&gt; Augments flow paths to achieve maximum flow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Edmonds-Karp Algorithm:&lt;/strong&gt; A specialized implementation of Ford Fulkerson using BFS for efficient augmentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dinic's Algorithm:&lt;/strong&gt; Optimizes the augmentation process, enhancing efficiency.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Understanding these graph problems and their solutions equips you with a powerful toolkit for tackling diverse challenges in computer science, optimization, and beyond. Whether you're navigating paths, exploring connectivity, or optimizing flows, these algorithms form the backbone of computational problem-solving.&lt;/p&gt;

&lt;p&gt;Connect with me on &lt;a href="https://www.linkedin.com/in/lokeswaran-aj/"&gt;LinkedIn&lt;/a&gt; &amp;amp; &lt;a href="https://twitter.com/lokeswaran_aj"&gt;X&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>javascript</category>
      <category>leetcode</category>
      <category>programming</category>
    </item>
    <item>
      <title>Backtracking made simple</title>
      <dc:creator>Lokeswaran Aruljothi</dc:creator>
      <pubDate>Mon, 25 Dec 2023 12:48:58 +0000</pubDate>
      <link>https://dev.to/lokeswaran-aj/backtracking-made-simple-5bjl</link>
      <guid>https://dev.to/lokeswaran-aj/backtracking-made-simple-5bjl</guid>
      <description>&lt;p&gt;Yesterday, I could not solve a single backtracking problem in &lt;a href="https://leetcode.com/tag/backtracking/"&gt;Leetcode&lt;/a&gt;. But I watched some &lt;a href="https://www.youtube.com/watch?v=Zq4upTEaQyM"&gt;YouTube videos&lt;/a&gt; to understand the algorithm, and today I am able to solve backtracking leetcode medium problems within 10 minutes. In this blog, I will tell you the trick that I learned to solve any backtracking problems and apply the trick to leetcode problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;Backtracking is a general algorithm for finding &lt;strong&gt;all (or some)&lt;/strong&gt; solutions to a computational problem that incrementally builds candidates for solutions and abandons a candidate ("backtracks") as soon as it determines that the candidate cannot possibly be completed to a valid solution&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vAG-N1xs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pv7fohi3bdvhkfm110hv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vAG-N1xs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pv7fohi3bdvhkfm110hv.jpg" alt="backtracking" width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  We can easily come up with the backtracking solution by answering the following three questions:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What is the goal of the problem?&lt;/li&gt;
&lt;li&gt;What are the choices that we can make?&lt;/li&gt;
&lt;li&gt;What is the constraint when making a choice?&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Here's a Python template for a backtracking algorithm:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;backtrack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;problem&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="c1"&gt;# check if the goal is reached
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;is_solution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;problem&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;process_solution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;problem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;next_candidate&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;generate_candidates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;problem&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

        &lt;span class="c1"&gt;# Check the constraint
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;is_valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;problem&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

            &lt;span class="c1"&gt;# Make a choice
&lt;/span&gt;            &lt;span class="nf"&gt;make_choice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;next_candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;problem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# Recursively call the backtracking method
&lt;/span&gt;            &lt;span class="nf"&gt;backtrack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;next_candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;problem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# Undo the choice (backtrack)
&lt;/span&gt;            &lt;span class="nf"&gt;undo_choice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;next_candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;problem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Let's solve the &lt;a href="https://leetcode.com/problems/combination-sum/description/"&gt;39. Combination Sum&lt;/a&gt; problem:
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Given an array of &lt;strong&gt;distinct&lt;/strong&gt; integers &lt;code&gt;candidates&lt;/code&gt; and a target integer &lt;code&gt;target&lt;/code&gt;, return a list of all &lt;strong&gt;unique combinations&lt;/strong&gt; of &lt;code&gt;candidates&lt;/code&gt; where the chosen numbers sum to &lt;code&gt;target&lt;/code&gt;. You may return the combinations in &lt;strong&gt;any order&lt;/strong&gt;.&lt;br&gt;
The &lt;strong&gt;same&lt;/strong&gt; number may be chosen from &lt;code&gt;candidates&lt;/code&gt; an &lt;strong&gt;unlimited number of times&lt;/strong&gt;. Two combinations are unique if the frequency of at least one of the chosen numbers is different.&lt;br&gt;
&lt;strong&gt;Example 1:&lt;/strong&gt;&lt;br&gt;
Input: candidates = [2,3,6,7], target = 7&lt;br&gt;
Output: [[2,2,3],[7]]&lt;br&gt;
Explanation:&lt;br&gt;
2 and 3 are candidates, and 2 + 2 + 3 = 7. Note that 2 can be used multiple times.&lt;br&gt;
7 is a candidate, and 7 = 7.&lt;br&gt;
These are the only two combinations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, let's answer the above three questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The goal is to find all the combinations of candidates or numbers that sum up to the &lt;code&gt;target&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The choices are all the numbers in the &lt;code&gt;candidates&lt;/code&gt; list. We can use the same number many times.&lt;/li&gt;
&lt;li&gt;The constraint is that if the sum of the current list is greater than the target, we can not choose that number.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Solution:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Solution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;combinationSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]]:&lt;/span&gt;
       &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;combinations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

       &lt;span class="c1"&gt;# calling the backtracking helper method
&lt;/span&gt;       &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;backtracking&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;combinations&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;backtracking&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;startIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currentSum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currentCombination&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Check if we reach the goal
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;currentSum&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;combinations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentCombination&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;startIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
            &lt;span class="n"&gt;currentSum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

            &lt;span class="c1"&gt;# Check the constraint
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;currentSum&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;currentSum&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;

            &lt;span class="c1"&gt;# Make a choice and call the backtracking function again
&lt;/span&gt;            &lt;span class="n"&gt;currentCombination&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;backtracking&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currentSum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currentCombination&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# Undo the choice
&lt;/span&gt;            &lt;span class="n"&gt;currentCombination&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;currentSum&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, I first initialized the &lt;code&gt;combinations&lt;/code&gt; list to hold the combinations. Then I called the backtracking method, which takes 5 arguments:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;candidates - input candidates list&lt;/li&gt;
&lt;li&gt;target - target number&lt;/li&gt;
&lt;li&gt;index - start index of the choice list&lt;/li&gt;
&lt;li&gt;currentSum - sum of the elements in the current list&lt;/li&gt;
&lt;li&gt;currentCombination - the current combination list
In &lt;code&gt;backtracking&lt;/code&gt; method, I first checked if I had reached the &lt;strong&gt;goal&lt;/strong&gt;, i.e., if the current sum was equal to the target, then I added the copy of the &lt;code&gt;currentCombination&lt;/code&gt; to the &lt;code&gt;combinations&lt;/code&gt; list.
I have a for loop which loops from the &lt;code&gt;startIndex&lt;/code&gt; to the &lt;code&gt;last&lt;/code&gt; element in the &lt;code&gt;candidates&lt;/code&gt;. I check the &lt;strong&gt;constraint&lt;/strong&gt;, i.e., if the &lt;code&gt;currentSum&lt;/code&gt; is less than the &lt;code&gt;target&lt;/code&gt;.
Then, I made the &lt;strong&gt;choice&lt;/strong&gt; of adding the element to my &lt;code&gt;currentCombination&lt;/code&gt; list and called the &lt;code&gt;backtracking&lt;/code&gt; method recursively.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Since we can use the same element multiple times, I have passed the current index as the value for &lt;code&gt;startIndex&lt;/code&gt;. If we can't use the same element, then pass &lt;code&gt;index+1&lt;/code&gt; as the value for &lt;code&gt;startIndex&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally, &lt;strong&gt;Undo the choice&lt;/strong&gt; by removing the element that was added.&lt;/p&gt;

&lt;h2&gt;
  
  
  Time and Space Complexities:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Time complexity: O(N*2^N)&lt;/li&gt;
&lt;li&gt;Space complexity: O(N)
where N is the length of the &lt;code&gt;candidates&lt;/code&gt; list.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Connect with me on &lt;a href="https://www.linkedin.com/in/lokeswaran-aj/"&gt;LinkedIn&lt;/a&gt; and &lt;a href="https://twitter.com/lokeswaran_aj"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>python</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
