<?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: Sergei Golitsyn</title>
    <description>The latest articles on DEV Community by Sergei Golitsyn (@golitsynsergei).</description>
    <link>https://dev.to/golitsynsergei</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%2F758793%2F3ae2ffdf-cde6-41f8-8d0d-dce7c5987752.jpg</url>
      <title>DEV Community: Sergei Golitsyn</title>
      <link>https://dev.to/golitsynsergei</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/golitsynsergei"/>
    <language>en</language>
    <item>
      <title>Award Budget Cuts</title>
      <dc:creator>Sergei Golitsyn</dc:creator>
      <pubDate>Mon, 13 Feb 2023 23:45:58 +0000</pubDate>
      <link>https://dev.to/golitsynsergei/award-budget-cuts-191o</link>
      <guid>https://dev.to/golitsynsergei/award-budget-cuts-191o</guid>
      <description>&lt;p&gt;Sergei Golitsyn provides solutions to popular algo problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aPxRk3Aw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dn47dvpdeyplnl7sd53u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aPxRk3Aw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dn47dvpdeyplnl7sd53u.jpg" alt="Image description" width="880" height="495"&gt;&lt;/a&gt;&lt;br&gt;
Aloha guys today we have a Pramp.com problem Award Budget Cuts:&lt;/p&gt;
&lt;h2&gt;
  
  
  Description
&lt;/h2&gt;

&lt;p&gt;Given an array grantsArray of the original grants and the reduced budget newBudget, write a function findGrantsCap that finds in the most efficient manner a cap such that the least number of recipients is impacted and that the new budget constraint is met (i.e. sum of the N reallocated grants equals to newBudget).&lt;/p&gt;

&lt;p&gt;Analyze the time and space complexities of your solution.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;input:  
grantsArray = [2, 100, 50, 120, 1000], 
newBudget = 190
output: 47 
And given this cap the new grants array would be
[2, 47, 47, 47, 47]. 
Notice that the sum of the new grants is indeed 190
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;This problem was mind-blowing for me. First, let's concentrate on the example and figure out what is happening. &lt;br&gt;
We have an array of old budgets and want to distribute new ones. In the best-case scenario, we want to distribute it evenly. For example, if &lt;code&gt;arr = [10, 10, 10]&lt;/code&gt; and &lt;code&gt;newBudg = 3&lt;/code&gt;, the correct &lt;code&gt;result should be 3&lt;/code&gt;. We will put 1 to all grants. &lt;br&gt;
Let's add more examples. &lt;code&gt;arr = [10, 3, 4, 200]&lt;/code&gt; and &lt;code&gt;newBudg = 8&lt;/code&gt;, &lt;code&gt;result = 2&lt;/code&gt;. Do you see a pattern? &lt;code&gt;arr = [10, 1, 2, 20]&lt;/code&gt; and &lt;code&gt;newBudg = 7&lt;/code&gt;, &lt;code&gt;result = 2&lt;/code&gt;. You can ask me why result 2 is correct in the last example. It happens because we can fill grand with budget 1, then we have the rest of the budget as 6. And we can evenly distribute it to 3 other grands.&lt;br&gt;
Hmm, so we have a pattern of how to solve this problem. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First of all, let's sort out the grants array.&lt;/li&gt;
&lt;li&gt;Then we can add variable &lt;code&gt;cap = newBudg / grants.length&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;After it, we should iterate over the collection and check the cap and current element.&lt;/li&gt;
&lt;li&gt;If the current element is lower than the cap, we can subtract it from the budget and recalculate the cap again with a lower length.&lt;/li&gt;
&lt;li&gt;We want to do it till we find the first &lt;code&gt;grand &amp;gt; cap&lt;/code&gt;. After it, it doesn't make sense. 
Our algorithm ready for implementation. Let's deep dive to the code implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static double findGrantsCap(double[] arr, double newBudget) {
   // your code goes here
   Arrays.sort(arr); // O(N*LogN)
   int n = arr.length-1;
   double cap = newBudget/n+1;
   for(int i = 0; i &amp;lt; n; i++) { // O(N)
     if(arr[i] &amp;lt; cap) {
        newBudget -= arr[i];
        cap = (newBudget/(n-i));
     } else {
       return cap;
     }
   }
   return cap;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>java</category>
      <category>leetcode</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Greatest Common Divisor of Strings</title>
      <dc:creator>Sergei Golitsyn</dc:creator>
      <pubDate>Fri, 10 Feb 2023 17:58:29 +0000</pubDate>
      <link>https://dev.to/golitsynsergei/greatest-common-divisor-of-strings-25e7</link>
      <guid>https://dev.to/golitsynsergei/greatest-common-divisor-of-strings-25e7</guid>
      <description>&lt;p&gt;Sergei Golitsyn provides solutions to popular leetcode problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DGY5BLfV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6hus4embf64t5thul3f6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DGY5BLfV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6hus4embf64t5thul3f6.jpg" alt="Image description" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aloha guys today we have a popular GDS problem:&lt;/p&gt;

&lt;h2&gt;
  
  
  Description
&lt;/h2&gt;

&lt;p&gt;For two strings s and t, we say "t divides s" if and only if s = t + ... + t (i.e., t is concatenated with itself one or more times).&lt;/p&gt;

&lt;p&gt;Given two strings str1 and str2, return the largest string x such that x divides both str1 and str2.&lt;/p&gt;

&lt;p&gt;Example 1:&lt;/p&gt;

&lt;p&gt;Input: str1 = "ABCABC", str2 = "ABC"&lt;br&gt;
Output: "ABC"&lt;br&gt;
Example 2:&lt;/p&gt;

&lt;p&gt;Input: str1 = "ABABAB", str2 = "ABAB"&lt;br&gt;
Output: "AB"&lt;br&gt;
Example 3:&lt;/p&gt;

&lt;p&gt;Input: str1 = "LEET", str2 = "CODE"&lt;br&gt;
Output: ""&lt;/p&gt;

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

&lt;p&gt;To solve it we need to understand, what we want to find. We need to find greatest common part of two words, and this part should divide word on 1-N the same paths. &lt;br&gt;
For example: &lt;code&gt;a = ABCABC&lt;/code&gt; and &lt;code&gt;b = ABC&lt;/code&gt; can be divided on &lt;code&gt;a = ABC ABC&lt;/code&gt; and &lt;code&gt;b = ABC&lt;/code&gt;&lt;br&gt;
In the next example &lt;code&gt;a = ABABAB&lt;/code&gt; and &lt;code&gt;b = ABAB&lt;/code&gt; we cannot divide a on b because &lt;code&gt;a = ABAB AB&lt;/code&gt; and &lt;code&gt;ABAB != AB&lt;/code&gt;. That is why we should reduce divider. &lt;br&gt;
   We can do it iteratively, but what if we start with the rest of the longest string? &lt;br&gt;
&lt;code&gt;a = ABABAB&lt;/code&gt; after divide a has two parts common &lt;code&gt;ABAB&lt;/code&gt; and rest &lt;code&gt;AB&lt;/code&gt;. Let's try to use rest. Now let's try to divide longest string on short one, &lt;code&gt;a = AB&lt;/code&gt; and &lt;code&gt;b = ABAB&lt;/code&gt;. b will be &lt;code&gt;AB AB&lt;/code&gt;. Hm, obviously that &lt;code&gt;AB&lt;/code&gt; is greatest common divisor. But how can we understand it? We need to dive bit deeper and again use rest of division. &lt;code&gt;a = ""&lt;/code&gt; and &lt;code&gt;b = AB&lt;/code&gt;. If one of the strings is empty, another one will be our result. Wisdom, right? &lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    public String gcdOfStrings2(String str1, String str2) {
        int l1 = str1.length();
        int l2 = str2.length();

        // Swap the parameters when needed
        if (l1 &amp;lt; l2){
            return gcdOfStrings(str2, str1);
        }

        // Since we swap
        if (l2 == 0){
            return str1;
        }

        // Check if str1 starts with str2
        if (!str1.startsWith(str2)) {
            return "";
        }

        return gcdOfStrings(str1.substring(l2), str2);
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>java</category>
      <category>leetcode</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Find the Duplicate Number</title>
      <dc:creator>Sergei Golitsyn</dc:creator>
      <pubDate>Wed, 26 Oct 2022 03:03:50 +0000</pubDate>
      <link>https://dev.to/golitsynsergei/find-the-duplicate-number-2lnl</link>
      <guid>https://dev.to/golitsynsergei/find-the-duplicate-number-2lnl</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0fp9AVPj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zhzq5rtarbwd4p9yo9qb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0fp9AVPj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zhzq5rtarbwd4p9yo9qb.jpg" alt="Image description" width="880" height="495"&gt;&lt;/a&gt;&lt;br&gt;
author: Sergei Golitsyn&lt;br&gt;
link: &lt;a href="https://leetcode.com/problems/find-the-duplicate-number/"&gt;https://leetcode.com/problems/find-the-duplicate-number/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Given an array of integers nums containing n + 1 integers where each integer is in the range [1, n] inclusive.&lt;/p&gt;

&lt;p&gt;There is only one repeated number in nums, return this repeated number.&lt;/p&gt;

&lt;p&gt;You must solve the problem without modifying the array nums and uses only constant extra space.&lt;/p&gt;

&lt;p&gt;`Example 1:&lt;br&gt;
Input: nums = [1,3,4,2,2]&lt;br&gt;
Output: 2&lt;/p&gt;

&lt;p&gt;Example 2:&lt;br&gt;
Input: nums = [3,1,3,4,2]&lt;br&gt;
Output: 3`&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ok ok, hello everyone. Let's try to solve this problem.&lt;br&gt;
We know that we have elements from 1 to n. &lt;br&gt;
And all this elements were sorted. &lt;br&gt;
What if &lt;br&gt;
&lt;strong&gt;&lt;em&gt;we will check the middle element and calculate count of elements less that the middle&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
If count less than middle element, that means that that we have duplicate element in the right part. &lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1,2,3,4,5,5,6]
mid = 4
foreach(1 : 6) --&amp;gt; 
if (num &amp;lt;= cur){
 count ++;
}
count = 1 (1)
...
count = 4 (4)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we have count as 4, that is why we have to move into right part. Is it clear? &lt;/p&gt;

&lt;p&gt;Then in the right part we can do the same. And move to the right or to the left part. &lt;/p&gt;

&lt;p&gt;Finally in the left part we set result as middle element, because otherwise we move to another side. &lt;/p&gt;

&lt;p&gt;And yes, it is a modified binary search. You seem simple algorithm for complicated problem. &lt;/p&gt;

&lt;p&gt;Sure you can iterate over array, and it would take O(N) time. In this approach we have O(log(N)) time complexity without additional memory. &lt;/p&gt;

&lt;p&gt;Full code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    public int findDuplicate(int[] nums) {
        int start = 1;
        int end = nums.length - 1;

        int rez = -1;

        while(start &amp;lt;= end){
            int cur = (end + start) / 2;

            int count = 0;
            for (int num : nums){
                if (num &amp;lt;= cur){
                    count ++;
                }
            }
            if (count &amp;gt; cur){
                rez = cur;
                end = cur - 1;
            } else {
                start = cur + 1;
            }

        }
        return rez;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>java</category>
      <category>leetcode</category>
      <category>interview</category>
      <category>software</category>
    </item>
    <item>
      <title>Linked List Popular problems</title>
      <dc:creator>Sergei Golitsyn</dc:creator>
      <pubDate>Fri, 17 Dec 2021 12:13:01 +0000</pubDate>
      <link>https://dev.to/golitsynsergei/linked-list-popular-problems-f0d</link>
      <guid>https://dev.to/golitsynsergei/linked-list-popular-problems-f0d</guid>
      <description>&lt;p&gt;Hello everyone. Today we will analyse popular tasks for linked lists.&lt;br&gt;
   Also you can check &lt;a href="https://dev.to/golitsynsergei/linked-list-tips-c81"&gt;Linked List Tips&lt;/a&gt;.&lt;br&gt;
The first task on our list is &lt;strong&gt;Merge Two Sorted Lists&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You are given the heads of two sorted linked lists list1 and list2.&lt;br&gt;
Merge the two lists in a one sorted list. The list should be made by splicing together the nodes of the first two lists.&lt;br&gt;
Return the head of the merged linked list.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;How do we approach this problem? One of the most popular techniques for working with linked lists is &lt;strong&gt;two-pointers.&lt;/strong&gt; In our case, we can use the beginning of each of the lists as pointers and move the elements only if one is larger than the other. Also, do not forget to supplement our resulting list with the remaining elements of the list that is longer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode empty = new ListNode();
        ListNode emptyHead = empty;

        while(list1 != null &amp;amp;&amp;amp; list2 != null) {
            if(list1.val &amp;gt; list2.val) {
                empty.next = list2;
                list2 = list2.next;
                empty = empty.next;
            } else {
                empty.next = list1;
                list1 = list1.next;
                empty = empty.next;
            }
        }

        while (list1 != null) {
            empty.next = list1;
            list1 = list1.next;
            empty = empty.next;
        }
        while (list2 != null) {
            empty.next = list2;
            list2 = list2.next;
            empty = empty.next;
        }
        return emptyHead.next;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will smoothly move on to the **Add Two Numbers **task.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You may assume the two numbers do not contain any leading zero, except the number 0 itself.&lt;br&gt;
   In our case, we need to add numbers. But there may be a situation when the amount will be more than 10. Then it is worth transferring the balance to the next operation. There is also a case when the sum is 10. Then you can take it out in a separate case or combine it with a condition greater than 10.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode rezNodeHead = new ListNode();
        ListNode rezNode = rezNodeHead;
        int rest = 0;
        while (l1 != null || l2 != null) {
            int val1 = (l1 != null) ? l1.val : 0;
            int val2 = (l2 != null) ? l2.val : 0;

            int rez = rest + val1 + val2;
            ListNode tmp = new ListNode();
            if (rez == 10) {
                tmp.val = 0;
                rezNode.next = tmp;
                rezNode = tmp;
                rest = 1;
            } else if (rez &amp;gt; 10) {
                int val = rez % 10;
                rest = rez / 10;
                tmp.val = val;
                rezNode.next = tmp;
                rezNode = tmp;
            } else {
                tmp.val = rez;
                rezNode.next = tmp;
                rezNode = tmp;
                rest = 0;
            }
            l1 = (l1 != null) ? l1.next : null;
            l2 = (l2 != null) ? l2.next : null;
        }
        if (rest != 0) {
            ListNode tmp = new ListNode();
            tmp.val = rest;
            rezNode.next = tmp;
        }
        return rezNodeHead.next;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;_   If you have any questions about this problem, I will be happy to answer._&lt;br&gt;
There is no way around &lt;strong&gt;Flatten a Multilevel Doubly Linked List&lt;/strong&gt;. In this task, a node can have a child node.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You are given a doubly linked list, which contains nodes that have a next pointer, a previous pointer, and an additional child pointer. This child pointer may or may not point to a separate doubly linked list, also containing these special nodes. These child lists may have one or more children of their own, and so on, to produce a multilevel data structure as shown in the example below.&lt;/p&gt;

&lt;p&gt;Given the head of the first level of the list, flatten the list so that all the nodes appear in a single-level, doubly linked list. Let curr be a node with a child list. The nodes in the child list should appear after curr and before curr.next in the flattened list.&lt;/p&gt;

&lt;p&gt;Return the head of the flattened list. The nodes in the list must have all of their child pointers set to null.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are several interesting approaches to solving this problem. I will analyse the easiest (for me) to write. It doesn't take long to write this approach. My idea is that we are running through the nodes. When the node has a child, we rearrange the link so that the list with the child sodas fits into our current list. There is a nuance that we will have to run through the child node two times in the worst case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static Node flatten(Node head) {
        Node headTmp = head;
        if (head == null) {
            return head;
        }

        while (head != null) {
            Node child = head.child;
            Node next = head.next;

            if (child != null) {
                head.next = child;

                while (child.next != null) {
                    child = child.next;
                }
                child.next = next;
                next.prev = child;
            }
            head.child = null;
            head = head.next;
        }
        return headTmp;
    } 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How can this algorithm be improved? When meeting a child node, it is possible to recursively into the depths of the list. We will embed it in the parent when we get to the most profound child element. Visually, it will look completely different from the previous algorithm.&lt;br&gt;
&lt;em&gt;If you have any questions, I will be happy to answer them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Do not forget about the rather popular **Odd-Even Linked List **task. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Given the head of a singly linked list, group all the nodes with odd indices together followed by the nodes with even indices, and return the reordered list.&lt;br&gt;
The first node is considered odd, and the second node is even, and so on.&lt;br&gt;
Note that the relative order inside both the even and odd groups should remain as it was in the input.&lt;br&gt;
You must solve the problem in O(1) extra space complexity and O(n) time complexity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can remember the technique of the &lt;strong&gt;two runners&lt;/strong&gt;. We can &lt;strong&gt;prepare two nodes for odd and even elements&lt;/strong&gt;, and we will successfully add them. In the end, we need to merge two lists. How to do it? For this, we &lt;strong&gt;need a tail&lt;/strong&gt;. Therefore, when filling underneath, we will shift a tail. And at the end, we combine tail odd and head even.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public ListNode oddEvenList(ListNode head) {
        if (head == null){
            return head;
        }
        ListNode oddHead = null;
        ListNode oddTail = null;
        ListNode evenHead = null;
        ListNode evenTail = null;
        int counter = 0;

        while(head != null) {
            counter += 1;
            if (counter % 2 != 0) {
                if (oddHead == null) {
                    oddHead = head;
                    oddTail = head;

                } else {
                    oddTail.next = head;
                    oddTail = head;
                }
            } else {
                if (evenHead == null) {
                    evenHead = head;
                    evenTail = head;

                } else {
                    evenTail.next = head;
                    evenTail = head;
                }
            }
            head = head.next;
        }

        oddTail.next = evenHead;
        if (evenTail != null){
            evenTail.next = null;
        }
        return oddHead;
    } 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>java</category>
      <category>tutorial</category>
      <category>leetcode</category>
      <category>interview</category>
    </item>
    <item>
      <title>Linked List Tips</title>
      <dc:creator>Sergei Golitsyn</dc:creator>
      <pubDate>Fri, 03 Dec 2021 14:25:20 +0000</pubDate>
      <link>https://dev.to/golitsynsergei/linked-list-tips-c81</link>
      <guid>https://dev.to/golitsynsergei/linked-list-tips-c81</guid>
      <description>&lt;p&gt;&lt;strong&gt;Linked List&lt;/strong&gt; is a fairly popular data structure. And the tasks associated with this structure can often be found at an interview. In this article, we will break down everyday Linked List tasks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1IAStvJl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8uytbg6i5jkcfhe1yxbf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1IAStvJl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8uytbg6i5jkcfhe1yxbf.png" alt="Image description" width="880" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Linked List is a linked list where one item refers to another.&lt;/p&gt;

&lt;p&gt;One of the &lt;strong&gt;most common techniques&lt;/strong&gt; for solving Linked List problems is the &lt;strong&gt;two sliders technique&lt;/strong&gt;. We create a &lt;strong&gt;fast&lt;/strong&gt; and &lt;strong&gt;slow&lt;/strong&gt; &lt;strong&gt;slider&lt;/strong&gt; and move the slow one forward, one non-zero. And fast (for example) by two.&lt;/p&gt;

&lt;p&gt;Task. &lt;strong&gt;Linked List Cycle&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Given head, the head of a linked list, determine if the linked list has a cycle in it.&lt;br&gt;
There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to. Note that pos is not passed as a parameter.&lt;br&gt;
Return true if there is a cycle in the linked list. Otherwise, return false&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ij259xIG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wuhsgx06x8hiiveeybpi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ij259xIG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wuhsgx06x8hiiveeybpi.png" alt="Image description" width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How can we know if there is a loop? If you create two sliders, when the slow one enters the loop, the fast one will catch up with it by 1. And it turns out they will meet. And if there is no loop, then the fast slider will be null. I hope the idea is clear. Let's take a look at the code:&lt;/p&gt;

&lt;p&gt;` public boolean hasCycle(ListNode head) {&lt;br&gt;
        if (head == null) {&lt;br&gt;
            return false;&lt;br&gt;
        } else {&lt;br&gt;
            ListNode slow = head;&lt;br&gt;
            ListNode fast = head;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        while(fast != null &amp;amp;&amp;amp; fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;

            if (slow == fast){
                return true;
            }
        }
    }
    return false;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;`&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do we find the node where the loop starts?&lt;/strong&gt; It is not hard to see from the previous algorithm that the fast slider will reach the slow one in N steps. Since our loop may not start from the beginning of the sheet, when the slow slider approaches the beginning of the loop after X steps, the fast slider will go X * 2. And the fast one will be at a distance of N - 2 * X steps. On the other hand, the fast catches up with the slow one by 1 every step. It turns out that the fast lags behind the slow one by N - 2X. Catching up each time by 1, the fast and slow runners will meet at point N - X. This means that we can move any slider to the beginning of the sheet and move the runners step by step from the meeting point and the head. The place where they meet will be the beginning of the loop. If you still have questions about the algorithm, write. I will be happy to answer.&lt;br&gt;
   Let's take a look at the code:&lt;/p&gt;

&lt;p&gt;`public ListNode detectCycle(ListNode head) {&lt;br&gt;
        if (head == null || head.next == null) {&lt;br&gt;
            return null;&lt;br&gt;
        }&lt;br&gt;
        ListNode slow = head;&lt;br&gt;
        ListNode fast = head;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    while (fast != null &amp;amp;&amp;amp; fast.next != null){
        slow = slow.next;
        fast = fast.next.next;

        if (slow == fast){
            break;
        }
    }

    if (fast == null || fast.next == null) {
        return null;
    }
    slow = head;

    while (slow != fast){
        slow = slow.next;
        fast = fast.next;
    }
    return slow;
} `
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Oh, I really like the next challenge. &lt;strong&gt;The intersection of Two Linked Lists.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wByJTlND--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yiv92ewuq1vkwtd8ijko.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wByJTlND--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yiv92ewuq1vkwtd8ijko.png" alt="Image description" width="880" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Given the heads of two singly linked-lists headA and headB, return the node at which the two lists intersect. If the two linked lists have no intersection at all, return null.&lt;/p&gt;

&lt;p&gt;How do we find these intersections? What if the length of the sheets is different? What if they don't intersect at all?&lt;/p&gt;

&lt;p&gt;I suggest that you first check if the sheets overlap.&lt;br&gt;
We just go through one and the second sheet and see that the resulting baud is the same.&lt;br&gt;
What to do next?&lt;br&gt;
During the first pass through the sheets, we can calculate the length of each of them. We get the missing number of nodes by subtracting the smaller size from the larger. With this amount, you can move along the sheet. And then, we can begin to run on two sheets and look for the place of their intersection. Cool, isn't it?&lt;/p&gt;

&lt;p&gt;`public ListNode getIntersectionNode(ListNode headA, ListNode headB) {&lt;br&gt;
        ListNode aEnd = headA;&lt;br&gt;
        ListNode bEnd = headB;&lt;br&gt;
        int aLength = 1;&lt;br&gt;
        int bLength = 1;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    while (aEnd != null){
        aEnd = aEnd.next;
        aLength++;
    }

    while (bEnd != null){
        bEnd = bEnd.next;
        bLength++;
    }

    if (aEnd != bEnd) {
        return null;
    }

    aEnd = headA;
    bEnd = headB;
    int shift = 0;
    if (aLength &amp;gt; bLength) {
        shift = aLength - bLength;
        while (shift &amp;gt; 0){
            aEnd = aEnd.next;
            shift --;
        }
    } else if (bLength &amp;gt; aLength) {
        shift = bLength - aLength;
        while (shift &amp;gt; 0){
            bEnd = bEnd.next;
            shift --;
        }
    }

    while(aEnd != null) {
        if (aEnd == bEnd){
            return aEnd;
        }
        aEnd = aEnd.next;
        bEnd = bEnd.next;
    }

    return null;
} `
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;By the way, &lt;strong&gt;have you ever wondered how you can remove a specific node from the end of the List?&lt;/strong&gt; After all, we only have one direction? &lt;strong&gt;How to delete?&lt;/strong&gt;&lt;br&gt;
Fast and slow runners come to our rescue again. Move the fast slider by the required number of elements.&lt;br&gt;
Next, connect the slow slider and run until the fast slider becomes NULL. When fast is NULL, the slow slider is in front of the element to be removed. And that's all. Then we can simply rearrange the links, and the required part is removed.&lt;/p&gt;

&lt;p&gt;`public ListNode removeNthFromEnd(ListNode head, int n) {&lt;br&gt;
        ListNode empty = new ListNode();&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    empty.next = head;
    ListNode slow = empty;
    ListNode fast = empty;

    for (int i = 0; i &amp;lt; n &amp;amp;&amp;amp; fast != null; i++){
        fast = fast.next;
    }

    while (fast != null &amp;amp;&amp;amp; fast.next != null){
        slow = slow.next;
        fast = fast.next;
    }

    slow.next = slow.next.next;
    return empty.next;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;`&lt;/p&gt;

&lt;p&gt;Let's summarize. When using the slider technique, always test the next element for NULL. It is necessary to correctly determine the conditions for ending the loop. Run different options to make sure your requirements are correct.&lt;/p&gt;

</description>
      <category>java</category>
      <category>algorithms</category>
      <category>leetcode</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
