# 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