diff --git a/README.md b/README.md index cc3806d7..bf71b048 100644 --- a/README.md +++ b/README.md @@ -612,3 +612,4 @@ Profile on LeetCode: [fartem](https://leetcode.com/fartem/). | 687. Longest Univalue Path | [Link](https://leetcode.com/problems/longest-univalue-path/) | [Link](./lib/medium/687_longest_univalue_path.rb) | [Link](./test/medium/test_687_longest_univalue_path.rb) | | 692. Top K Frequent Words | [Link](https://leetcode.com/problems/top-k-frequent-words/) | [Link](./lib/medium/692_top_k_frequent_words.rb) | [Link](./test/medium/test_692_top_k_frequent_words.rb) | | 701. Insert into a Binary Search Tree | [Link](https://leetcode.com/problems/insert-into-a-binary-search-tree/) | [Link](./lib/medium/701_insert_into_a_binary_search_tree.rb) | [Link](./test/medium/test_701_insert_into_a_binary_search_tree.rb) | +| 707. Design Linked List | [Link](https://leetcode.com/problems/design-linked-list/) | [Link](./lib/medium/707_design_linked_list.rb) | [Link](./test/medium/test_707_design_linked_list.rb) | diff --git a/leetcode-ruby.gemspec b/leetcode-ruby.gemspec index 3eb52933..d1c4ae29 100644 --- a/leetcode-ruby.gemspec +++ b/leetcode-ruby.gemspec @@ -5,7 +5,7 @@ require 'English' ::Gem::Specification.new do |s| s.required_ruby_version = '>= 3.0' s.name = 'leetcode-ruby' - s.version = '7.4.7' + s.version = '7.4.8' s.license = 'MIT' s.files = ::Dir['lib/**/*.rb'] + %w[README.md] s.executable = 'leetcode-ruby' diff --git a/lib/medium/707_design_linked_list.rb b/lib/medium/707_design_linked_list.rb new file mode 100644 index 00000000..88d674c0 --- /dev/null +++ b/lib/medium/707_design_linked_list.rb @@ -0,0 +1,118 @@ +# frozen_string_literal: true + +# https://leetcode.com/problems/design-linked-list/ +class MyLinkedList + # Init + def initialize + @head = nil + @length = 0 + end + + # @param {Integer} index + # @return {Integer} + def get(index) + return -1 unless is_valid_index(index) + + node_at_index(index).val + end + + # @param {Integer} val + # @return {Void} + def add_at_head(val) + new_head = ::MyLinkedList::InnerListNode.new(val) + if @head + prev = @head + @head = new_head + new_head.next = prev + else + @head = new_head + end + + @length += 1 + end + + # @param {Integer} val + # @return {Void} + def add_at_tail(val) + if @head + tail = node_at_index(@length - 1) + tail&.next = ::MyLinkedList::InnerListNode.new(val) + else + @head = ::MyLinkedList::InnerListNode.new(val) + end + + @length += 1 + end + + # @param {Integer} index + # @param {Integer} val + # @return {Void} + def add_at_index(index, val) + if is_valid_index(index) + if index.zero? + add_at_head(val) + else + prev = node_at_index(index - 1) + nxt = node_at_index(index) + new_node = ::MyLinkedList::InnerListNode.new(val) + prev.next = new_node + new_node.next = nxt + end + + @length += 1 + elsif index == @length + add_at_tail(val) + end + end + + # @param {Integer} index + # @return {Void} + def delete_at_index(index) + return unless is_valid_index(index) + + if index.zero? + if @head + @head = @head.next + @length -= 1 + end + else + prev = node_at_index(index - 1) + prev.next = prev.next ? prev.next.next : nil + @length -= 1 + end + + puts(@length) + end + + # InnerListNode + class InnerListNode + attr_accessor :val, :next + + # @param {Integer} val + def initialize(val) + @val = val + @next = nil + end + end + + private + + # @param {Integer} index + # @return {Boolean} + def is_valid_index(index) = index >= 0 && index < @length + + # @param {Integer} index + # @return {ListNode} + def node_at_index(index) + return @head if index.zero? + + target = @head + position = 0 + until position == index + target = target.next + position += 1 + end + + target + end +end diff --git a/test/medium/test_707_design_linked_list.rb b/test/medium/test_707_design_linked_list.rb new file mode 100644 index 00000000..1ac2997d --- /dev/null +++ b/test/medium/test_707_design_linked_list.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require_relative '../test_helper' +require_relative '../../lib/medium/707_design_linked_list' +require 'minitest/autorun' + +class DesignLinkedListTest < ::Minitest::Test + def test_default_one + my_linked_list = ::MyLinkedList.new + my_linked_list.add_at_head(1) + my_linked_list.add_at_tail(3) + my_linked_list.add_at_index(1, 2) + + assert_equal(2, my_linked_list.get(1)) + + my_linked_list.delete_at_index(1) + + assert_equal(3, my_linked_list.get(1)) + end + + def test_additional_one + my_linked_list = ::MyLinkedList.new + my_linked_list.add_at_tail(1) + my_linked_list.add_at_index(0, 1) + my_linked_list.delete_at_index(0) + + assert_equal(1, my_linked_list.get(0)) + + my_linked_list.add_at_index(2, 2) + end +end