< Summary

Information
Class: LeetCode.Algorithms.AllOneDataStructure.AllOneDataStructureLinkedList
Assembly: LeetCode
File(s): D:\a\LeetCode-CS\LeetCode-CS\source\LeetCode\Algorithms\AllOneDataStructure\AllOneDataStructureLinkedList.cs
Line coverage
89%
Covered lines: 99
Uncovered lines: 12
Coverable lines: 111
Total lines: 203
Line coverage: 89.1%
Branch coverage
81%
Covered branches: 31
Total branches: 38
Branch coverage: 81.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
Inc(...)80%101085.71%
Dec(...)80%101085.18%
GetMaxKey()75%5466.66%
GetMinKey()75%5466.66%
MoveKey(...)100%22100%
InsertNodeAfter(...)100%22100%
RemoveNode(...)100%44100%
GetFirstKey(...)50%22100%
.ctor(...)100%11100%
get_Count()100%11100%
get_KeysHashSet()100%11100%
get_PreviousNode()100%11100%
get_NextNode()100%11100%

File(s)

D:\a\LeetCode-CS\LeetCode-CS\source\LeetCode\Algorithms\AllOneDataStructure\AllOneDataStructureLinkedList.cs

#LineLine coverage
 1// --------------------------------------------------------------------------------
 2// Copyright (C) 2026 Eugene Eremeev (also known as Yevhenii Yeriemeieiv).
 3// All Rights Reserved.
 4// --------------------------------------------------------------------------------
 5// This software is the confidential and proprietary information of Eugene Eremeev
 6// (also known as Yevhenii Yeriemeieiv) ("Confidential Information"). You shall not
 7// disclose such Confidential Information and shall use it only in accordance with
 8// the terms of the license agreement you entered into with Eugene Eremeev (also
 9// known as Yevhenii Yeriemeieiv).
 10// --------------------------------------------------------------------------------
 11
 12namespace LeetCode.Algorithms.AllOneDataStructure;
 13
 14/// <inheritdoc />
 15public sealed class AllOneDataStructureLinkedList : IAllOneDataStructure
 16{
 517    private readonly Node _headNode = new(int.MinValue);
 518    private readonly Dictionary<string, Node> _keyNodeDictionary = new();
 519    private readonly Node _tailNode = new(int.MaxValue);
 20
 521    public AllOneDataStructureLinkedList()
 522    {
 523        _headNode.NextNode = _tailNode;
 524        _tailNode.PreviousNode = _headNode;
 525    }
 26
 27    /// <summary>
 28    ///     Time complexity - O(1)
 29    ///     Space complexity - O(n)
 30    /// </summary>
 31    /// <param name="key"></param>
 32    public void Inc(string key)
 1733    {
 1734        if (_keyNodeDictionary.TryGetValue(key, out var currentNode))
 735        {
 736            var nextNode = currentNode.NextNode;
 37
 738            if (nextNode == null)
 039            {
 040                return;
 41            }
 42
 743            if (nextNode.Count != currentNode.Count + 1)
 544            {
 545                var newNode = new Node(currentNode.Count + 1);
 46
 547                InsertNodeAfter(currentNode, newNode);
 48
 549                nextNode = newNode;
 550            }
 51
 752            MoveKey(key, currentNode, nextNode);
 753        }
 54        else
 1055        {
 1056            if (_headNode.NextNode == null)
 057            {
 058                return;
 59            }
 60
 1061            if (_headNode.NextNode.Count != 1)
 762            {
 763                var newNode = new Node(1);
 64
 765                InsertNodeAfter(_headNode, newNode);
 766            }
 67
 1068            _headNode.NextNode.KeysHashSet.Add(key);
 1069            _keyNodeDictionary[key] = _headNode.NextNode;
 1070        }
 1771    }
 72
 73    /// <summary>
 74    ///     Time complexity - O(1)
 75    ///     Space complexity - O(n)
 76    /// </summary>
 77    /// <param name="key"></param>
 78    public void Dec(string key)
 479    {
 480        if (!_keyNodeDictionary.TryGetValue(key, out var currentNode))
 081        {
 082            return;
 83        }
 84
 485        if (currentNode.Count == 1)
 286        {
 287            _keyNodeDictionary.Remove(key);
 88
 289            currentNode.KeysHashSet.Remove(key);
 90
 291            if (currentNode.KeysHashSet.Count == 0)
 192            {
 193                RemoveNode(currentNode);
 194            }
 295        }
 96        else
 297        {
 298            var prevNode = currentNode.PreviousNode;
 99
 2100            if (prevNode == null)
 0101            {
 0102                return;
 103            }
 104
 2105            if (prevNode.Count != currentNode.Count - 1)
 1106            {
 1107                var newNode = new Node(currentNode.Count - 1);
 108
 1109                InsertNodeAfter(prevNode, newNode);
 110
 1111                prevNode = newNode;
 1112            }
 113
 2114            MoveKey(key, currentNode, prevNode);
 2115        }
 4116    }
 117
 118    /// <summary>
 119    ///     Time complexity - O(1)
 120    ///     Space complexity - O(n)
 121    /// </summary>
 122    /// <returns></returns>
 123    public string GetMaxKey()
 6124    {
 6125        if (_tailNode.PreviousNode == null)
 0126        {
 0127            return string.Empty;
 128        }
 129
 6130        return _tailNode.PreviousNode == _headNode ? string.Empty : GetFirstKey(_tailNode.PreviousNode);
 6131    }
 132
 133    /// <summary>
 134    ///     Time complexity - O(1)
 135    ///     Space complexity - O(n)
 136    /// </summary>
 137    /// <returns></returns>
 138    public string GetMinKey()
 6139    {
 6140        if (_headNode.NextNode == null)
 0141        {
 0142            return string.Empty;
 143        }
 144
 6145        return _headNode.NextNode == _tailNode ? string.Empty : GetFirstKey(_headNode.NextNode);
 6146    }
 147
 148    private void MoveKey(string key, Node fromNode, Node toNode)
 9149    {
 9150        fromNode.KeysHashSet.Remove(key);
 151
 9152        if (fromNode.KeysHashSet.Count == 0)
 4153        {
 4154            RemoveNode(fromNode);
 4155        }
 156
 9157        toNode.KeysHashSet.Add(key);
 158
 9159        _keyNodeDictionary[key] = toNode;
 9160    }
 161
 162    private static void InsertNodeAfter(Node prevNode, Node newNode)
 13163    {
 13164        newNode.PreviousNode = prevNode;
 13165        newNode.NextNode = prevNode.NextNode;
 166
 13167        if (prevNode.NextNode != null)
 13168        {
 13169            prevNode.NextNode.PreviousNode = newNode;
 13170        }
 171
 13172        prevNode.NextNode = newNode;
 13173    }
 174
 175    private static void RemoveNode(Node node)
 5176    {
 5177        if (node.PreviousNode != null)
 5178        {
 5179            node.PreviousNode.NextNode = node.NextNode;
 5180        }
 181
 5182        if (node.NextNode != null)
 5183        {
 5184            node.NextNode.PreviousNode = node.PreviousNode;
 5185        }
 5186    }
 187
 188    private static string GetFirstKey(Node node)
 10189    {
 10190        return node.KeysHashSet.Count > 0 ? node.KeysHashSet.First() : string.Empty;
 10191    }
 192
 23193    private class Node(int count)
 194    {
 61195        public int Count { get; } = count;
 196
 84197        public HashSet<string> KeysHashSet { get; } = [];
 198
 70199        public Node? PreviousNode { get; set; }
 200
 154201        public Node? NextNode { get; set; }
 202    }
 203}