From 17b729ce60d67e9cfa79eca45b4f32940b185edc Mon Sep 17 00:00:00 2001 From: fartem Date: Tue, 26 Nov 2024 07:56:48 +0300 Subject: [PATCH] 2024-11-26 v. 7.1.1: added "450. Delete Node in a BST" --- .rubocop.yml | 2 + README.md | 1 + leetcode-ruby.gemspec | 2 +- lib/common/binary_tree.rb | 4 +- lib/medium/450_delete_node_in_a_bst.rb | 45 +++++++ test/medium/test_450_delete_node_in_a_bst.rb | 128 +++++++++++++++++++ 6 files changed, 179 insertions(+), 3 deletions(-) create mode 100644 lib/medium/450_delete_node_in_a_bst.rb create mode 100644 test/medium/test_450_delete_node_in_a_bst.rb diff --git a/.rubocop.yml b/.rubocop.yml index 02672c3c..7126a350 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -28,6 +28,8 @@ Bundler/GemComment: Metrics/AbcSize: Enabled: false +Metrics/ClassLength: + Enabled: false Metrics/MethodLength: Enabled: false Metrics/CyclomaticComplexity: diff --git a/README.md b/README.md index ca035327..5d822219 100644 --- a/README.md +++ b/README.md @@ -576,3 +576,4 @@ Profile on LeetCode: [fartem](https://leetcode.com/fartem/). | 443. String Compression | [Link](https://leetcode.com/problems/string-compression/) | [Link](./lib/medium/443_string_compression.rb) | [Link](./test/medium/test_443_string_compression.rb) | | 445. Add Two Numbers II | [Link](https://leetcode.com/problems/add-two-numbers-ii/) | [Link](./lib/medium/445_add_two_numbers_ii.rb) | [Link](./test/medium/test_445_add_two_numbers_ii.rb) | | 449. Serialize and Deserialize BST | [Link](https://leetcode.com/problems/serialize-and-deserialize-bst/) | [Link](./lib/medium/449_serialize_and_deserialize_bst.rb) | [Link](./test/medium/test_449_serialize_and_deserialize_bst.rb) | +| 450. Delete Node in a BST | [Link](https://leetcode.com/problems/delete-node-in-a-bst/) | [Link](./lib/medium/450_delete_node_in_a_bst.rb) | [Link](./test/medium/test_450_delete_node_in_a_bst.rb) | diff --git a/leetcode-ruby.gemspec b/leetcode-ruby.gemspec index b59e46fb..9539054a 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.1.0' + s.version = '7.1.1' s.license = 'MIT' s.files = ::Dir['lib/**/*.rb'] + %w[README.md] s.executable = 'leetcode-ruby' diff --git a/lib/common/binary_tree.rb b/lib/common/binary_tree.rb index f46dcb3d..9e627bf2 100644 --- a/lib/common/binary_tree.rb +++ b/lib/common/binary_tree.rb @@ -17,8 +17,8 @@ def initialize(val = 0, left = nil, right = nil) # @param {TreeNode} other # @return {Boolean} def self.are_equals(curr, other) - return true if curr.nil? && other.nil? - return false if curr.nil? || other.nil? + return true if !curr && !other + return false if !curr || !other curr_eq = curr.val == other.val left_eq = are_equals(curr.left, other.left) diff --git a/lib/medium/450_delete_node_in_a_bst.rb b/lib/medium/450_delete_node_in_a_bst.rb new file mode 100644 index 00000000..2f3f751a --- /dev/null +++ b/lib/medium/450_delete_node_in_a_bst.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +# https://leetcode.com/problems/delete-node-in-a-bst/ +# @param {TreeNode} root +# @param {Integer} key +# @return {TreeNode} +def delete_node450(root, key) + return unless root + + if key > root.val + root.right = delete_node450(root.right, key) + elsif key < root.val + root.left = delete_node450(root.left, key) + elsif !root.left && !root.right + root = nil + elsif root.right + root.val = successor(root) + root.right = delete_node450(root.right, root.val) + else + root.val = predecessor(root) + root.left = delete_node450(root.left, root.val) + end + + root +end + +private + +# @param {TreeNode} node +# @return {Integer} +def successor(node) + node = node.right + node = node.left while node.left + + node.val +end + +# @param {TreeNode} node +# @return {Integer} +def predecessor(node) + node = node.left + node = node.right while node.right + + node.val +end diff --git a/test/medium/test_450_delete_node_in_a_bst.rb b/test/medium/test_450_delete_node_in_a_bst.rb new file mode 100644 index 00000000..449f24c3 --- /dev/null +++ b/test/medium/test_450_delete_node_in_a_bst.rb @@ -0,0 +1,128 @@ +# frozen_string_literal: true + +require_relative '../test_helper' +require_relative '../../lib/common/binary_tree' +require_relative '../../lib/medium/450_delete_node_in_a_bst' +require 'minitest/autorun' + +class DeleteNodeInABSTTest < ::Minitest::Test + def test_default_one + assert( + ::TreeNode.are_equals( + ::TreeNode.new( + 5, + ::TreeNode.new( + 4, + ::TreeNode.new(2), + nil + ), + ::TreeNode.new( + 6, + nil, + ::TreeNode.new(7) + ) + ), + delete_node450( + ::TreeNode.new( + 5, + ::TreeNode.new( + 3, + ::TreeNode.new(2), + ::TreeNode.new(4) + ), + ::TreeNode.new( + 6, + nil, + ::TreeNode.new(7) + ) + ), + 3 + ) + ) + ) + end + + def test_default_two + assert( + ::TreeNode.are_equals( + ::TreeNode.new( + 5, + ::TreeNode.new( + 2, + nil, + ::TreeNode.new(4) + ), + ::TreeNode.new( + 6, + nil, + ::TreeNode.new(7) + ) + ), + delete_node450( + ::TreeNode.new( + 5, + ::TreeNode.new( + 2, + nil, + ::TreeNode.new(4) + ), + ::TreeNode.new( + 6, + nil, + ::TreeNode.new(7) + ) + ), + 0 + ) + ) + ) + end + + def test_default_three + assert( + ::TreeNode.are_equals( + nil, + delete_node450( + nil, + 0 + ) + ) + ) + end + + def test_additional_one + assert( + ::TreeNode.are_equals( + ::TreeNode.new( + 10, + ::TreeNode.new(10), + ::TreeNode.new(10) + ), + delete_node450( + ::TreeNode.new( + 10, + ::TreeNode.new(10), + ::TreeNode.new(10) + ), + 20 + ) + ) + ) + end + + def test_additional_two + assert( + ::TreeNode.are_equals( + ::TreeNode.new(10), + delete_node450( + ::TreeNode.new( + 8, + ::TreeNode.new(10), + nil + ), + 8 + ) + ) + ) + end +end